在以下情况中捕获boost::make_iterator_range
的返回值的正确做法是什么:
在基于循环的范围中使用时:
for (auto&& val : boost::make_iterator_range(...))// <-- is `auto&&` the right way?
用作形式参数时:
DoStuff(boost::make_iterator_range(...));
template<class Iterator>
void DoStuff(Iterator&& it){}// <-- is Iterator&& the right way?
答案 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&& r
和auto&&
都是合理的方法,但在第一种情况下Range&&
,auto const&
或auto&
也是如此,在第二个auto
或Range const&
中有其优势。它们只是意味着不同的东西。
所以你的解决方案是正确的一种方式,但没有一种正确的方法&#34;什么放在那里。我默认使用转发引用,但这是一个品味问题:其他人可能会选择默认为Range
或值。在某些情况下,const&
是正确的(在你的循环修改值并希望修改保持不变的地方)。