为什么 const 临时绑定到右值引用参数?

问题描述

我有以下功能

void func(void * const &ptr)
{
    std::cerr << "const" << std::endl;
}

void func(void *      &&ptr)
{
    std::cerr << "mutable" << std::endl;
}

void* const func2()
{
    return nullptr;
}

一个重载采用 const 引用参数,另一个采用可变右值引用。还有一个返回常量值的函数

当我将 const 临时值传递给函数时:

func(func2());

我希望选择 const 重载。但我得到了:

mutable

这怎么可能?为什么 const 返回值绑定到非 const rvalue 引用参数

当我将 const void* 传递给函数而不是 struct 时,这不会发生:

struct A
{
};

void func(A const &a)
{
    std::cerr << "const" << std::endl;
}

void func(A      &&a)
{
    std::cerr << "mutable" << std::endl;
}

A const func3()
{
    return A(); 
}

int main()
{
    func(func3());
    return 0;
}

结果是:

const

您可以在 coliru 上查看。

const void* 和 const struct 有什么区别?

有没有一种方法可以使重载特别采用 const 值?

解决方法

为什么 const 临时绑定到右值引用参数?

因为在重载解析发生时它不是常量。

[expr.type]

2 如果纯右值最初具有“cv T”类型,其中 T 是 cv 未限定的非类、非数组类型,则表达式的类型在任何进一步分析之前调整为 T .

类类型纯右值保留其 cv 限定,但不保留 const images = [ { folder_name: 'folder 001',file_name: ['anh 1','anh 2','anh 3'] },{ folder_name: 'folder 002','anh 3','anh 4'] } ] 纯右值。因此,重载解析发生在普通的 void* const 纯右值上,这解释了您在选择右值重载时观察到的行为。

本段适用的类型是那些其值实际上被程序访问的“基本”类型。所以这种类型的纯右值确实是一个“纯”的、短暂的值,并且已经不能被修改。