在C ++中,允许在for循环中更改循环变量:
for( int i = 0; i < limit; i++ ) {
if( condition ) {
i--;
}
}
现在,如果一个循环体相当复杂,那么对于读者来说,循环变量是否在循环体 内改变了 并不是很明显。以某种方式调整代码是很好的,这样一旦读者只看到for-loop头,他就会立即知道循环变量没有改变 在体内 。 / p>
例如,如果我使用 然后很明显,无论在 对于C ++中的for循环控制变量,有没有办法实现类似的东西 - 迭代中的逻辑const?const
:const int value = computeValue();
//lots of code here
const
变量定义下面编写什么代码,变量都不会改变。
答案 0 :(得分:4)
我不认为这对于手工制作的循环是可行的,但我猜这可以被认为是鼓励使用std::for_each和BOOST_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
。这隐藏了循环变量/迭代器。