c++ - 通过转发的迭代循环的范围

标签 c++ c++11 argument-passing c++14

假设我有以下情况

template<typename T>
void func(T&& arg)
{
    for (auto elem : arg) // ***
    {
        // do stuff
    }
}

其中 arg 是迭代器( vector 或初始化列表等)。我对 *** 行感兴趣:以下哪项更好:

auto elem
auto& elem
`const` of the above

我想选项 (3) 包含在参数推导中(如果需要的话,auto 会在那里放置一个常量)。 func 的调用也是如此

func(std::forward<T>(arg)); 

改变了什么?

最佳答案

使用 auto对于基于范围的变量声明 for loop 几乎总是是错误的。只有在保证范围使用未突变的内置对象的情况下,它才是正确的。我通常不会使用 auto在这里(公平地说,我也不会首先基于范围的 for,但更喜欢算法)。

使用 auto&约束 *it 的结果对于迭代器 it超出范围为 T&T const&对于一些合适的类型 T .例如,它不允许迭代 std::vector<bool> .如果允许元素发生变异,那是一个合理的选择。使用 auto const&约束 *it 的结果要么是一个左值,要么有一个复制构造函数,并且将防止范围被改变。根据用途,这可能是一个合理的选择。

一般来说,默认选择应该是auto&&因为这对 *it 的结果没有任何限制。除了不是 void .

所以,总结一下:

  • for (auto elem: arg)如果元素必须是内置的并且没有发生变化。
  • for (auto& elem: arg)如果元素是左值并且允许改变。
  • for (auto const& elem: arg)如果元素是左值但未发生变异。
  • for (auto&& elem: arg)在所有无关紧要的情况下。我想总是使用 auto&&没问题。

关于c++ - 通过转发的迭代循环的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29195679/

相关文章:

c++ - 使用 uint64_t 作为内存的通用地址而不是 void* 有什么优缺点?

c++ - vector 第一个指针的变化

c++ - 用 C++ 扩展 Job/Worker 多线程系统

c++ - 将从 "midnight 1904-1-1"开始的秒数转换为日期时间字符串

c++ - 在 C++11 lambda 表达式中使用超出范围的变量

c++ - 如果对象在下一步被破坏,为什么不自动 move ?

c++ - 给定一个元素的地址搜索二维数组

带有 'new' 数组参数的 C++ 函数调用

c++ - 如何将 'double*' 传递给类函数,并将该值应用于该类中的另一个 'double*'

c++ - 二分无向图测试: Converting to check nodes with strings instead of integers