【发布时间】:2012-08-30 13:37:56
【问题描述】:
这个程序:
#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 中的错误?
【问题讨论】:
-
我认为是命名对象通常不能被移动(见那里的#2),但是
return t;有一个明显的漏洞,它可以破坏命名的-对象规则并移动(参见#1)。但我不确定。如果有人确定,请发布答案。 -
@Matthew 谢谢!它已解决“扩展”问题,因此委员会愿意对其进行更改,但不认为当前的行为是错误。
-
对。看起来 CWG 认为这不是一个错误并将其踢给了 EWG,最近在没有太多动静的情况下进行了讨论(基本上,我们同意它是 NAD,但我们愿意进行改进)。我不确定谁(如果有的话)正在积极追求这一点,但欢迎您通过标准提案摇摆并四处询问。
标签: c++ c++11 return move-semantics comma-operator