为什么 const 临时绑定到右值引用参数?
Why is const temporary bound to rvalue reference parameter?
我有以下功能:
void func(void * const &ptr)
{
std::cerr << "const" << std::endl;
}
void func(void * &&ptr)
{
std::cerr << "mutable" << std::endl;
}
void* const func2()
{
return nullptr;
}
一个重载采用常量引用参数,另一个采用可变右值引用。还有一个函数是 returns const value.
当我将该 const 临时值传递给函数时:
func(func2());
我希望选择 const 重载。但是我得到:
mutable
这怎么可能?为什么 const return 值绑定到非 const 右值引用参数?
然而,当我将 const struct
传递给函数而不是 void*
时,这不会发生:
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 值?
Why is const temporary bound to rvalue reference parameter?
因为在重载解析发生时它不是 const。
[expr.type]
2 If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
class 类型的纯右值保留其 cv 限定,但不保留 void* const
纯右值。因此,重载决议发生在一个普通的 void*
prvalue 上,这解释了您在选择右值重载时观察到的行为。
本段适用的类型是那些“基本”类型,其值实际上被程序访问。所以这种类型的纯右值确实是一个“纯”的、短暂的值,并且不能被修改。
我有以下功能:
void func(void * const &ptr)
{
std::cerr << "const" << std::endl;
}
void func(void * &&ptr)
{
std::cerr << "mutable" << std::endl;
}
void* const func2()
{
return nullptr;
}
一个重载采用常量引用参数,另一个采用可变右值引用。还有一个函数是 returns const value.
当我将该 const 临时值传递给函数时:
func(func2());
我希望选择 const 重载。但是我得到:
mutable
这怎么可能?为什么 const return 值绑定到非 const 右值引用参数?
然而,当我将 const struct
传递给函数而不是 void*
时,这不会发生:
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 值?
Why is const temporary bound to rvalue reference parameter?
因为在重载解析发生时它不是 const。
[expr.type]
2 If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
class 类型的纯右值保留其 cv 限定,但不保留 void* const
纯右值。因此,重载决议发生在一个普通的 void*
prvalue 上,这解释了您在选择右值重载时观察到的行为。
本段适用的类型是那些“基本”类型,其值实际上被程序访问。所以这种类型的纯右值确实是一个“纯”的、短暂的值,并且不能被修改。