在 C++11 中是否有更优雅的方法可以执行以下操作

Is there a more elegant way to do the following in C++11?

本文关键字:方法 执行 操作 C++11 是否      更新时间:2023-10-16

我想避免关于无符号 int 和有符号 int 之间比较的警告。

我使用如下循环:

for (int i =0 ; i < vec.size(); i++) {
 // do something
}

它给出了这些警告(这本身很好,我想要高级别的警告)。

我想把它改成以下内容:

for (auto i = vec.size()*0; i < vec.size(); i++) {
 // do something
}

在这种情况下,我没有得到警告。但我想知道是否有比这更优雅的东西,它会自动推断出迭代器所需的类型。

使用基于范围的 for 循环

for (auto& i : vec)
{
    cout << *i;
}

使用迭代器。

for (auto it = vec.begin(), end_it = vec.end(); it != end_it; ++it)
{
    cout << *it;
}

如果你想要一个计数器,如果你懒惰,请使用std::vector<T>::size_typesize_t

如果这是一个选项,请首选来自 <algorithm> 的标准库高阶原语,例如(不限于):

  • std::accumulate
  • std::copy
  • std::transform

当与 lambda 一起使用时,它们非常富有表现力。仅当无法选择时才使用for,并且更喜欢范围循环。

甚至是降序循环:

auto i = vec.size();
while (i --> 0)
   // ...

因为问题以短语开头:

"我想避免关于无符号int和 签名 int"

我假设vec.size()返回unsigned int.

如果 vec.size() 返回的类型可以存储在unsigned int中,则可以使用以下方法。

for (auto i = 0u; i < vec.size(); i++) {
       // do something
}

否则,请使用适当的类型或检查其他答案。

如果vec是类型 std::vector<T>(没有提到,因此上面的代码),你也可以使用 for_each 循环(也没有提到)

std::for_each(vec.begin(), vec.end(), [](T t){ /* do something with t */ });
std::for_each(vec.begin(), vec.end(), [](T & t){ /* do something with t */});
std::for_each(vec.begin(), vec.end(), [](const T & t){ /* do something with t */ });

如果您必须使用一些已经存在的函数对象(或方法或非成员函数)遍历向量元素,它会更方便

void f(int x) { std::cout << "f: " << x << "n"; }
void g(int x) { std::cout << "g: " << x << "n"; }
...
std::vector<int> vec{1, 2, 3};
std::for_each(vec.begin(), vec.end(), std::bind(f, std::placeholders::_1)); //calls f(int)
std::for_each(vec.begin(), vec.end(), std::bind(g, std::placeholders::_1)); //calls g(int)

更方便,因为您可以保留花哨的回调并根据需要将其设置为适当的功能

std::function<void(int)> callback = std::bind(f, std::placeholders::_1);
if (userWantsG())
   callback = std::bind(g, std::placeholders::_1);
std::for_each(vec.begin(), vec.end(), callback); //calls g or f