是否有任何值得选择的理由,例如性能或安全性?
std::vector<std::string> some_vec{ "a","b","c"};
std::vector<std::string>::const_iterator iter = some_vec.begin();
std::vector<std::string>::const_iterator end = some_vec.end();
while( iter++ != end ){Do}
-
std::vector<std::string> some_vec{ "a","b","c"};
std::vector<std::string>::const_iterator iter = some_vec.begin();
while( iter++ != some_vec.end() ){Do}
答案 0 :(得分:2)
第一个依赖于end
在循环期间不会失效:
// some_vec initialised with data!
std::vector<std::string> some_vec;
std::vector<std::string>::const_iterator iter = some_vec.begin();
//std::vector<std::string>::const_iterator end = some_vec.end();
while( iter++ != some_vec.end() ){
if (p(*iter)) iter = some_vec.insert(iter, "foo");
}
insert
可能会使所有迭代器无效,因此end
不能用于比较。
出于效率考虑,我不会太担心。如果some_vec.end()
总是返回相同的迭代器,则希望编译器意识到这一点并执行适当的优化。
答案 1 :(得分:2)
首先,while( iter++ != end ){Do}
是错误的。您最终将在循环主体中具有结束迭代器。要解决此问题,我们可以使用quick-bench.com来查看性能是否存在差异:
#include <vector>
static void test0(benchmark::State& state)
{
std::vector<std::string> some_vec{ "a", "b", "c" };
for (auto _ : state)
{
auto iter = some_vec.cbegin();
auto end = some_vec.cend();
while (iter != end)
{
auto ch = (*iter++)[0];
benchmark::DoNotOptimize(ch);
}
}
benchmark::DoNotOptimize(some_vec);
}
// Register the function as a benchmark
BENCHMARK(test0);
static void test1(benchmark::State& state)
{
// Code before the loop is not measured
std::vector<std::string> some_vec{ "a", "b", "c" };
for (auto _ : state)
{
auto iter = some_vec.cbegin();
while (iter != some_vec.cend())
{
auto ch = (*iter++)[0];
benchmark::DoNotOptimize(ch);
}
}
benchmark::DoNotOptimize(some_vec);
}
BENCHMARK(test1);
在没有优化和gcc 8.2的情况下,test0
的速度提高了1.3倍:
优化级别为O3
test0
快1.1倍:
使用Clang 7,它们几乎是相同的:
因此,性能似乎不是问题,但如果最终插入者可以以某种方式失效,则第二个版本更安全。