r 值引用返回类型语义?
Posted
技术标签:
【中文标题】r 值引用返回类型语义?【英文标题】:r-value reference return type semantics? 【发布时间】:2012-04-14 15:52:07 【问题描述】:这样的返回类型是否代表了 c++11 中有意义的东西?
template <typename R>
R&& grabStuff();
T instance = grabStuff<T>();
如果R
没有移动构造函数,我希望grabStuff
应该抛出编译时错误,因为这似乎不允许返回类型使用复制构造函数
【问题讨论】:
【参考方案1】:与往常一样,在返回引用时,您必须返回对函数返回后仍然存在的对象的引用。你如何做到这一点取决于你。示例:
T global_thing;
T && get() return std::move(global_thing);
struct Foo Foo(T &&); /* ... */ ;
int main()
global_thing.reset();
Foo a(get());
global_thing.reset();
Foo b(get());
返回右值引用的更典型示例是std::move
本身,它返回对您传递给它的东西的引用(因此调用者有责任提供有效输入)。
【讨论】:
对象不必是全局对象。管理资源的本地对象也是一个例子(我的意思是,也许 :D)。 @Kerrek,所以你的意思是这个函数应该只在临时调用?不能将您示例中get()
的结果分配给Foo&
的正常引用吗?
@Nawaz:是的,正如我所说,这取决于你...我只是想举一个例子,它不是 std::move
本身。
@lurscher:您也可以将结果绑定到引用:Foo && rr = get();
。【参考方案2】:
如果函数的返回类型是一个右值引用,那么函数调用的结果就是一个xvalue;如果返回类型是非引用,那么函数调用的结果就是prvalue。
xvalue 和 prvalue 都是右值,它们之间存在一些细微的差异,更像是引用和非引用之间的差异。例如,一个 xvalue 可能有一个不完整的类型,而一个纯右值通常应该有一个完整的类型或 void 类型。当 typeid 应用于类型为多态类类型的 xvalue 时,结果引用动态类型;而对于纯右值,结果是指静态类型。
对于你的声明语句T instance = grabStuff<T>();
,如果T是类类型,我认为在这种情况下xvalue和prvalue没有区别。
初始化器是一个右值,所以编译器更喜欢移动构造器。但是如果没有声明move构造函数,并且声明了一个带有const引用参数的拷贝构造函数,那么就会选择这个拷贝构造函数,并且不会出错。我不知道你为什么希望这是一个错误。如果这是一个错误,任何旧代码在从右值复制初始化某些对象时都会不正确。
【讨论】:
【参考方案3】:它可能有意义,具体取决于您想用它做什么,以及您如何实现该功能。
实际上,std::move
返回类型是T&&
(右值引用),这很有意义,因为它定义了 C++11 库中存在 std::move
的真正目的:
【讨论】:
std::move
是右值引用返回类型的唯一有意义的实例。它在用户代码中永远不会有意义。
@ildjarn:我不能声称“它永远不会在用户代码中有意义”。我只是说 rvalue-reference 作为返回类型,可能是有意义的。
我声称。 ;-] 在用户代码中(除非用户代码出于某种奇怪的原因复制std::move
),右值引用返回类型不能做任何语义上有意义的事情。
@ildjarn:现在声称这种东西还为时过早; C++11 刚刚发布,在接下来的 10 年里,将会发现许多技巧和习语。所以我宁愿保持双手交叉。
您可以 A) 获得悬空引用或 B) 暗示 所有权变更而不保证所有权,这是完全没用的。就是这样。以上是关于r 值引用返回类型语义?的主要内容,如果未能解决你的问题,请参考以下文章