如何在C ++ for-loop体内显示循环控制变量没有改变?

时间:2010-11-23 11:45:41

标签: c++ loops for-loop const

在C ++中,允许在for循环中更改循环变量:

for( int i = 0; i < limit; i++ ) {
    if( condition ) {
       i--;
    }
}

现在,如果一个循环体相当复杂,那么对于读者来说,循环变量是否在循环体 内改变了 并不是很明显。以某种方式调整代码是很好的,这样一旦读者只看到for-loop头,他就会立即知道循环变量没有改变 在体内 。 / p>

例如,如果我使用const

const int value = computeValue();
//lots of code here

然后很明显,无论在const变量定义下面编写什么代码,变量都不会改变。

对于C ++中的for循环控制变量,有没有办法实现类似的东西 - 迭代中的逻辑const?

9 个答案:

答案 0 :(得分:4)

我不认为这对于手工制作的循环是可行的,但我猜这可以被认为是鼓励使用std::for_eachBOOST_FOREACH进行STL容器迭代的另一个参数

编辑 ...和C ++ 0x range-based for-loop(感谢Matthieu。M:)

答案 1 :(得分:2)

这是一个很好的问题,让我思考如何做到这一点以及解决方法。没有花太多时间,我唯一想到的就是:

int limit = 10;
for(int i(0), guard(0); i < limit; i++, guard++)
{
         // lots of code here
    assert(i == guard);
}

显然,用户仍然可以在循环中修改后卫,但顶部的无效可能会显示它将被检查。

答案 2 :(得分:2)

C ++ 0x有趣。此代码未编译:

for (int i = 0; i < 10; ++i)
{
    [&, i] ()
    {
        if ( i == 5 )
        {
            ++i;
        }
        cout << i << endl;
    }();
}

错误: 'i':不能在非可变lambda中修改按值捕获

答案 3 :(得分:2)

将for_each与boost::counting_iterator结合使用,并使用接受const int的函数。

for_each(boost::counting_iterator<int>(0), boost::counting_iterator<int>(limit),
    [&](const int i)
    {
        // do something with i
    });

答案 4 :(得分:1)

没有逻辑构造来强制执行此操作。如果你把'const int idx = i'作为循环中的第一个语句,然后只使用'idx',你可能能够实现类似的强制执行但却失去了一些清晰度。否则,只需使用评论。

答案 5 :(得分:1)

从技术上讲,你可以这样做。

int main()
{
    for( int i = 0;  i < 42;  ++i )
    {{
        typedef void    i;

        i = 666;        // !Nope.
    }}
}

如果您想要在循环体内访问i,则必须在const之前提供备用名称(引用typedef)。

但我不推荐这种技术解决方案,因为它不明确且不常见,所以对读者来说并不明显。

相反,只需重构大循环。 : - )

答案 6 :(得分:1)

您可以使for循环的整个主体成为一个单独的函数,循环控制变量的范围超出了该函数。

我想不出一个简单的方法来做你想要的,因为循环控制变量是定义可变的,以便控制循环。

答案 7 :(得分:1)

使用带有 FILE LINE 的宏创建一个奇怪的对象,后者可能作为模板参数(它是编译时常量?)。在增加它时,必须使用相同的 FILE LINE 。那么同样的路线可能就足够了。如果它不在同一行,则可能会出现编译错误。

template< int line > 
class Counter
{
 // stuff
public:
   bool valid() const;
   static void inc( Counter<line> & counter );  
};

for( Counter<__LINE__> counter( n ); counter.valid(); Counter<__LINE__>::inc( counter ) )
{
 // body

   // what __LINE__ do I need to use here to increment counter? Can be done but won't be
}

我还没有测试过。只是一个想法。

答案 8 :(得分:0)

您可能会尝试将“循环”变量名称更改为长而荒谬的名称,以便在循环内触摸它(不止一次)会刮伤眼睛。

还有一些像使用专用循环宏,例如BOOST_FOREACH。这隐藏了循环变量/迭代器。