在C ++ 11中捕获prvalue的正确方法

时间:2016-07-19 05:50:18

标签: c++ c++11

在以下情况中捕获boost::make_iterator_range的返回值的正确做法是什么:

  1. 在基于循环的范围中使用时:

    for (auto&& val : boost::make_iterator_range(...))//  <-- is `auto&&` the right way?
    
  2. 用作形式参数时:

    DoStuff(boost::make_iterator_range(...));
    
    template<class Iterator>
    void DoStuff(Iterator&& it){}//  <-- is Iterator&& the right way?
    

1 个答案:

答案 0 :(得分:0)

for (auto&& val : boost::make_iterator_range(...))//  <-- is `auto&&` the right way?

make_iterator_range的返回值未存储在val中。 val只存储迭代器解除引用的返回值:元素,而不是整个范围。

auto&&创建对元素的转发引用。

DoStuff(boost::make_iterator_range(...));

template<class Iterator>
void DoStuff(Iterator&& it){}//  <-- is Iterator&& the right way?

使用名称Iterator掩盖了一个误解:make_itetator_range不是迭代器,它是由迭代器定义的范围。

template<class Range>
void DoStuff(Range&& r){}

这不会改变代码的行为,但它就像是一个名为int的{​​{1}}类型的变量:毫无意义或过于混乱。

在任何情况下,此上下文中的Double也是转发引用。

类型推导上下文中的转发引用可以绑定到左值或右值。它也可能导致参考寿命延长。

在这两种情况下,Range&& rauto&&都是合理的方法,但在第一种情况下Range&&auto const&auto&也是如此,在第二个autoRange const&中有其优势。它们只是意味着不同的东西。

所以你的解决方案是正确的一种方式,但没有一种正确的方法&#34;什么放在那里。我默认使用转发引用,但这是一个品味问题:其他人可能会选择默认为Range或值。在某些情况下,const&是正确的(在你的循环修改值并希望修改保持不变的地方)。