代码之家  ›  专栏  ›  技术社区  ›  sharptooth

如何显示循环控制变量在C++循环体中没有改变?

  •  9
  • sharptooth  · 技术社区  · 13 年前

    在C++中,允许for循环中的循环变量被允许:

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

    现在,如果一个循环体相当复杂,那么读者不会立即发现是否更改了循环变量 环体内 . 以某种方式调整代码会很好,这样一旦读者只看到for循环头,他就会立即知道循环变量没有更改 体内 .

    const :

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

    很明显,无论代码写在 常量 变量定义变量不变。

    是否有类似的方法实现迭代中的逻辑一致性——在C++中for for循环控制变量的情况下?

    9 回复  |  直到 13 年前
        1
  •  4
  •   icecrime    13 年前

    我不认为这是可能的手工循环,但我想这可以被视为一个额外的论点,以鼓励使用 std::for_each BOOST_FOREACH 用于STL容器上的迭代。

    编辑 range-based for-loop (谢谢马蒂厄。M:)

        2
  •  2
  •   Moo-Juice    13 年前

    这是一个很好的问题,让我想到了你应该怎么做,怎么解决。不用花太多时间,我唯一想到的是:

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

        3
  •  2
  •   Benjamin Lindley    13 年前

    用于 boost::counting_iterator 以及接受常量int的函数。

    for_each(boost::counting_iterator<int>(0), boost::counting_iterator<int>(limit),
        [&](const int i)
        {
            // do something with i
        });
    
        4
  •  2
  •   Alex F    13 年前

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

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

        5
  •  1
  •   fmt Peter DeGlopper    13 年前

    没有逻辑结构来强制执行此操作。如果您将const int idx=i作为循环中的第一个语句,然后只使用idx,您可能能够实现类似的强制,但会失去一些清晰性。否则,只需使用注释。

        6
  •  1
  •   Steve Townsend    13 年前

    您可以使for循环的整个主体成为一个单独的函数,循环控制变量不在该函数的作用域内。

        7
  •  1
  •   CashCow    13 年前

    用宏创建一个奇怪的对象 文件 生产线 ,后者可能作为模板参数(它是编译时常量吗?)。当您增加它时,它必须使用相同的 文件 . 好吧,同一条线可能就足够了。如果不在同一行,则可能会出现编译器错误。

    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
  •  1
  •   Tim Cooper    13 年前

    int main()
    {
        for( int i = 0;  i < 42;  ++i )
        {{
            typedef void    i;
    
            i = 666;        // !Nope.
        }}
    }
    

    如果你想访问 i const )在 typedef .

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

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

        9
  •  0
  •   valdo    13 年前

    还有一些类似于使用专用循环宏,例如 BOOST_FOREACH . 这将隐藏循环变量/迭代器。