这个程序:
#include <iostream>
struct T {
T() {}
T(const T &) { std::cout << "copy constructor "; }
T(T &&) { std::cout << "move constructor "; }
};
int main() {
([](T t) -> T { return t; })({}); std::cout << '\n';
([](T t) -> T { return void(), t; })({}); std::cout << '\n';
([](T t) -> T { return void(), std::move(t); })({}); std::cout << '\n';
}
当由 gcc-4.7.1 编译时输出(link):
move constructor
copy constructor
move constructor
为什么逗号运算符有这样的效果呢?标准说:
5.18 逗号运算符[expr.comma]
1 - [...] 类型
和结果的值是右操作数的类型和值;结果与其右操作数具有相同的值类别[...]。如果右操作数的值是临时的,则结果就是该临时的。
我是否错过了一些允许逗号运算符影响程序语义的东西,或者这是 gcc 中的一个错误?
自动移动基于复制省略的资格:
§12.8 [class.copy] p32
当满足或将满足复制操作的省略条件时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定之外,选择复制构造函数的重载决策为首先执行时就好像该对象是由右值指定的一样。 [...]
当返回表达式为自动对象的名称.
§12.8 [class.copy] p31
in a return
具有类返回类型的函数中的语句,当表达式是非易失性自动对象的名称时(函数或catch子句参数除外)与函数返回类型具有相同的cv非限定类型,可以通过将自动对象直接构造到函数的返回值中来省略复制/移动操作
插入逗号运算符后,表达式不再是自动对象的名称,而只是对一个对象的引用,这会抑制复制省略。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)