3

我正在使用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()

4

2 回答 2

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)(在原始的基于范围的 for 语句中使用冒号后的表达式begin-expr),本质上是begin(__range)并且end-expr本质上是end(__range)


在这种情况下,以下代码是否正确且良好的做法?

我将提供替代方案而不是判断(->代码审查):

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.
    }
}
于 2013-11-05T22:37:01.197 回答
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
}  

这避免了所有检查是否是第一个元素,并且不会添加太多代码

于 2013-11-05T22:58:08.413 回答