【问题标题】:r-value reference return type semantics?r 值引用返回类型语义?
【发布时间】:2012-04-14 15:52:07
【问题描述】:

这样的返回类型是否代表了 c++11 中有意义的东西?

template <typename R>
R&& grabStuff();

T instance = grabStuff<T>();

如果R 没有移动构造函数,我希望grabStuff 应该抛出编译时错误,因为这似乎不允许返回类型使用复制构造函数

【问题讨论】:

    标签: c++ c++11 rvalue-reference


    【解决方案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&amp; 的正常引用吗?
    • @Nawaz:是的,正如我所说,这取决于你...我只是想举一个例子,它不是 std::move本身。
    • @lurscher:您也可以将结果绑定到引用:Foo &amp;&amp; rr = get();
    【解决方案2】:

    如果函数的返回类型是一个右值引用,那么函数调用的结果就是一个xvalue;如果返回类型是非引用,那么函数调用的结果就是prvalue。

    xvalue 和 prvalue 都是右值,它们之间存在一些细微的差异,更像是引用和非引用之间的差异。例如,一个 xvalue 可能有一个不完整的类型,而一个纯右值通常应该有一个完整的类型或 void 类型。当 typeid 应用于类型为多态类类型的 xvalue 时,结果引用动态类型;而对于纯右值,结果是指静态类型。

    对于你的声明语句T instance = grabStuff&lt;T&gt;();,如果T是类类型,我认为在这种情况下xvalue和prvalue没有区别。

    初始化器是一个右值,所以编译器更喜欢移动构造器。但是如果没有声明move构造函数,并且声明了一个带有const引用参数的拷贝构造函数,那么就会选择这个拷贝构造函数,并且不会出错。我不知道你为什么希望这是一个错误。如果这是一个错误,任何旧代码在从右值复制初始化某些对象时都会不正确。

    【讨论】:

      【解决方案3】:

      它可能有意义,具体取决于您想用它做什么,以及您如何实现该功能。

      实际上,std::move 返回类型是T&amp;&amp;(右值引用),这很有意义,因为它定义了 C++11 库中存在 std::move 的真正目的:

      【讨论】:

      • std::move 是右值引用返回类型的唯一有意义的实例。它在用户代码中永远不会有意义。
      • @ildjarn:我不能声称“它永远不会在用户代码中有意义”。我只是说 rvalue-reference 作为返回类型,可能是有意义的。
      • 我声称。 ;-] 在用户代码中(除非用户代码出于某种奇怪的原因复制std::move),右值引用返回类型不能做任何语义上有意义的事情。
      • @ildjarn:现在声称这种东西还为时过早; C++11 刚刚发布,在接下来的 10 年里,将会发现许多技巧和习语。所以我宁愿保持双手交叉。
      • 您可以 A) 获得悬空引用或 B) 暗示 所有权变更而不保证所有权,这是完全没用的。就是这样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2020-12-15
      相关资源
      最近更新 更多