临时常量数组未绑定到右值引用
Temporary const array not binding to rvalue reference
我有以下测试程序:
#include <iostream>
#include <type_traits>
#include <utility>
template<typename Ty, std::size_t N>
void foo(Ty (&&)[N])
{
std::cout << "Ty (&&)[" << N << "]t" << std::is_const<Ty>::value << 'n';
}
template<typename Ty, std::size_t N>
void foo(Ty (&)[N])
{
std::cout << "Ty (&)[" << N << "]t" << std::is_const<Ty>::value << 'n';
}
template<typename Ty>
using id = Ty;
int main()
{
std::cout.setf(std::cout.boolalpha);
foo(id<int[]>{1, 2, 3, 4, 5});
foo(id<int const[]>{1, 2, 3, 4, 5}); // <-- HERE.
int xs[]{1, 2, 3, 4, 5};
foo(xs);
int const ys[]{1, 2, 3, 4, 5};
foo(ys);
foo(std::move(xs));
foo(std::move(ys));
}
我希望用箭头标记的行会调用右值重载,就像它上面的非常量调用一样,但它没有。
这只是GCC中的一个错误,还是标准中有什么东西导致选择左值重载?
根据标准§12.2 [class.temporary]
:
类类型的临时性是在各种上下文中创建的:绑定引用prvalue(8.5.3),返回prvalue(6.6.3)创建prvalue(4.1、5.2.9、5.2.11、5.4)的转换,抛出一个异常(15.1),输入一个处理程序(15.3),在某些情况下初始化(8.5)。
因此id<int const[]>{1, 2, 3, 4, 5}
是临时的,因此是一个prvalue §3.10 [basic.lval]
:
右值(历史上之所以这么叫,是因为右值可能出现在赋值表达式的右侧)是一个x值临时对象(12.2)或其子对象,或不是与对象关联。
prvalue("纯"右值)是一个不是xvalue的右值。
因此,应选择带有右值引用参数的重载函数。
相关文章:
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 将常量指针引用绑定到非常量指针
- 运行时错误:引用绑定到类型为"int"的空指针
- 模板允许左值与右值引用绑定
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 无法将类型"T&"的非常量左值引用绑定到类型"T"的右值 t++ std::atomic<T>
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 将引用绑定到指针的语法是什么?(各种)
- 为什么我不能将常量左值引用绑定到返回 T&&&的函数?
- 为什么 VS 无法将右值引用绑定到指针?
- 出于什么原因,有必要将常量左值引用绑定到右值?
- 为什么此右值引用绑定到左值?
- 使用“void*”将右值引用绑定到左值
- 排序时引用绑定到 'value_type' 类型的 null 指针
- 无法将类型为"类名 &"的非常量左值引用绑定到类型为"类名"的右值
- 引用绑定和复制构造函数/移动构造函数
- 将引用绑定到类型的值会删除限定符 MULTISET
- 无法将类型"int&"的非常量左值引用绑定到类型为"int"的右值
- 多态变体,并将一种类型的引用绑定到另一种类型的引用
- C++17:是编译器为(静态存储持续时间)const引用绑定创建的可修改的临时对象(和存储)