我正在使用std::vector
,其中第一个元素是某种特殊的,并且需要与其他元素进行稍微不同的处理。
我想使用基于C ++ 11范围的for循环以获得更高的可读性,在这种情况下,以下代码是否正确并且是良好的实践?
std::vector<T> v;
// [...] build v
bool isFirst = true;
for(auto element : v)
{
// [...] do lots of things common to all elements
if(isFirst)
{
// [...] do something that only applies to the first element
}
// [...] do lots of things common to all elements
isFirst = false;
}
从技术上讲,当使用基于范围的for循环std::vector
时,保证按顺序处理元素,从v.front()
到v.back()
?
答案 0 :(得分:4)
是保证按顺序处理的元素
是
for
形式的基于范围的for ( for-range-declaration : expression ) statement
将被等效地评估为:[stmt.ranged] / 1
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}
range-init 是(expression)
(在原始基于范围的语句中冒号后面带有表达式),begin-expr
基本上是begin(__range)
,end-expr
基本上是end(__range)
。
在这种情况下,以下代码是否正确和良好实践?
我会提供一种替代方案,而非评判方式( - &gt; Code Review):
template<class It>
struct range
{
It beg;
It en;
It begin() { return beg; }
It end() { return en; }
};
template<class It>
range<It> make_range(It beg, It en) { return {beg, en}; }
std::vector<int> v;
if(v.size() > 0)
{
auto r = make_range(begin(v)+1, end(v));
for(auto const& e : r)
{
// do.
}
}
答案 1 :(得分:2)
是的,当然是按顺序处理它们,否则它们的用途非常有限。这是你可以做到的另一种方式。
std::vector<T> v;
// [...] build v
auto front = v.front();
/* do stuff to first */
for(auto iter = v.begin()+1; iter != v.end() ; ++iter)
{
//*iter is now the element incase you didn't know how iterators work
// [...] do lots of things common to all elements
}
这可以避免所有检查成为第一个元素,并且不会添加太多代码