【发布时间】:2018-02-16 06:44:23
【问题描述】:
以下代码返回一个只能移动的类型,然后应通过转换构造函数将其转换为另一种类型。
#include <utility>
class Foo
{
public:
Foo() {}
Foo(const Foo&) = delete;
Foo(Foo&&) = default;
};
class Other
{
public:
Other(Foo foo) {}
};
Other moo()
{
Foo foo;
return foo;
}
int main()
{
moo();
}
这给我的编译器带来了一个错误,只能通过在 return 语句中添加 std::move 来修复,这被认为是不好的做法,因为通常它会阻止返回值优化。是不是应该先把return语句的标识符当作右值来满足转换?
这段代码有效吗?这里是哪个编译器?
- g++、c++14:编译:http://coliru.stacked-crooked.com/a/f25ae94e8ca9c5c8
- g++-4.8、c++11:无法编译:http://coliru.stacked-crooked.com/a/0402e3ebf97fd0e7
- clang++,c++14:不编译:http://coliru.stacked-crooked.com/a/682d8ca93d3e2f6a
【问题讨论】:
-
IIRC、C++11 和 C++14 在这一点上有所不同。
-
@Jarod42 在那种情况下,我希望两个编译器都同意 C++14 模式。
-
编译器不必对此达成一致。可悲的是,这种复制省略只是他们可能做的事情。不是他们必须做的事。允许 Clang 完全无视它可以用副本代替移动的事实。
-
@user2079303 - 这是非常可选的。
[class.copy]描述了整个事情的地方,并没有强制实现省略任何内容。它仅指定实现何时允许的先决条件。 -
@user2079303 - 你知道的。我们在这件事上白费力气。 OP 没有返回与函数返回值具有相同(可能是 cv 限定)类型的对象。不符合 p31 中指定的省略标准。所以这没有实际意义。
标签: c++ language-lawyer move-semantics rvalue