C++11 "T&&"参数失去其"&&"正确的术语?
C++11 `T&&` parameter losing its `&&` correct terminology?
以下c++ 11代码无法编译:
struct T {};
void f(T&&) { }
void g(T&& t) { f(t); }
int main()
{
g(T());
}
正确的方法是:
void g(T&& t) { f(move(t)); }
这很难用正确的自然语言术语来解释。参数t
似乎失去了它的"&&"状态,它需要与std::move
一起恢复。
g(T())
中的T()
叫什么?
g(T&& t)
中的T&&
是什么?
g(T&& t)
中的t
是什么?
f(t)
和f(move(t))
中的t
是什么?
move(t)
的返回值是什么?
你认为整体效果是什么?
标准的哪个部分处理这个问题?
关键是参数T&& b
只能绑定到右值,但是当以后引用表达式b
时,它是左值。
所以函数的实参必须是右值,但在函数体内部,形参是左值,因为这时你已经绑定了对它的引用并给了它一个名字,它不再是一个未命名的临时对象了。
表达式具有类型(例如int
, string
等),并且具有值类别(例如左值或右值),这两者是不同的。
声明为T&& b
的命名变量类型为"对T
的右值引用",并且只能绑定到右值,但是当您稍后使用该引用时,表达式b
具有值类别"左值",因为它有名称并引用某个对象(无论引用绑定到什么对象,即使该对象是右值)。这意味着将b
传递给另一个接受右值的函数,你不能只说f(b)
,因为b
是左值,所以你必须通过std::move(b)
将它(返回)转换为右值。
所有参数都是左值,即使它们的类型是"右值引用"。它们都有名字,所以你可以随时引用它们。如果命名的右值引用是右值,您将得到令人惊讶的行为。我们不希望从左值隐式移动,这就是为什么你必须显式地写std::move
。
g(T())中的T()叫什么?
临时的(可移动的)。
你叫什么T&&在g (T&和;
t) ?
T&和;是一个r值引用,表示一个可以移动的对象。
g(t &&
t) ?
t实际上是一个左值,因为您可以通过名称引用它。
f(t)和f(move(t))中的t叫什么?
- l值
- 当move()返回时将l值转换为r值引用
move(t)的返回值是什么?
r值引用
作为注释;你可能应该调用结构体C,并写一个单独的例子,其中T实际上是模板化的。代码需要不同,因为在函数template< typename T > void f( T&& t );
中,您不能简单地使用std::move()
而不小心非常,因为T实际上可以是const&
,在这种情况下,您不能使用std::move()
,而是使用完美转发与std::forward< T >( t )
g(T())中的T()叫什么?
这是一个临时对象和r值。
你叫什么T&&在g (T&和;
t) ?
你称它为r值引用
原因
void g(T&& t) { f(t); }
不能工作是因为r值引用不能绑定到命名对象(即使该命名对象恰好是另一个r值引用)。
参数t
不丢失其"状态"。简单地说,参数t
是一个左值,尽管它是一个右值引用。请记住,左值和右值是正交的概念,适用于值和值引用(包括右值引用)。因此,右值引用既可以是左值,也可以是右值。如果它有一个名称,就像在您的示例中一样,它是一个左值。这使得类型系统正交,这是一个很好的特性。
- 主.cpp:18:20:错误:从"int*"转换为"int"会失去精度 [-fa
- 启动类函数作为失去引用的线程
- 临时对象:术语澄清
- std::bind 和 std::函数术语不值为接受 0 个参数?
- 我想在C++代码中比较这三个术语
- 为什么对引用的常量引用会失去其恒定性?
- 当指针在 cpp 17 中失去引用时,是否会调用非默认析构函数?
- 理解一个特定的C++代码块及其术语
- 术语的计算结果不是采用0个参数的函数
- 错误 C2064:术语的计算结果不是采用 3 个参数的函数
- C++,术语,非规范,阻塞,检测消息结束
- 使shared_ptr失去对内存的所有权
- 从"SymbolInfo*"转换为"YYSTYPE {aka int}"会失去精
- C++:从 "const variable*" 转换为"uint32"会失去精度
- 具有成员的类的术语
- 数组在返回时失去价值(库存/菜单程序)C++
- 术语不计算为函数采用 1 个参数错误?
- 将用户输入的术语与 txt 文件中的列表进行比较
- "overriding"非虚拟方法的官方术语
- C++11 "T&&"参数失去其"&&"正确的术语?