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

几乎总是自动和for循环,带计数器[闭合]

  •  1
  • Alex  · 技术社区  · 7 年前

    赫伯萨特州 Almost Always Auto 我有以下代码:

    using count_t = int;
    count_t get_count() { ... };
    
    const auto count = get_count();
    for (decltype(count) i = 0; i < count; i++) {
        // Do the stuff
    }
    

    基本上,使用 decltype() 允许我编写一个for循环,可以使用任何整数类型(希望 get_count() 在客户端代码中没有任何修改的情况下,将永远不会返回浮点 函数并避免编译警告,如“signed unsigned”不匹配。

    我的问题是:如果假设 count_t 将来可能会被重新定义?

    4 回复  |  直到 7 年前
        1
  •  3
  •   Jarod42    7 年前

    要保持AAA,您可以访问:

    for (auto i = decltype(count){}; i != count; ++i) { /*..*/ }
    
        2
  •  4
  •   Praetorian Luchian Grigore    7 年前

    如果可以选择使用Boost,就可以避免所有的噪音

    #include <boost/range/irange.hpp>
    
    for(auto i : boost::irange(get_count()))
    

    的单参数版本 boost::irange 是在1.68中引入的,因此您需要复制 implementation 对于早期版本。

        3
  •  2
  •   Yakk - Adam Nevraumont    7 年前
    template<class T>
    struct indexer_t {
      T t;
      T operator*()const{return t;}
      void operator++(){++t;}
      friend bool operator==(indexer_t const& lhs, indexer_t const& rhs) {
        return lhs.t==rhs.t;
      }
      friend bool operator!=(indexer_t const& lhs, indexer_t const& rhs) {
        return lhs.t!=rhs.t;
      }
    };
    template<class It>
    struct range_t {
      It b,e;
      It begin() const { return b; }
      It end() const { return e; }
    };
    template<class T>
    range_t<indexer_t<T>> count_over( T const& s, T const& f ) {
      return { {s}, {f} };
    }
    template<class T>
    range_t<indexer_t<T>> count_upto( T const& t ) {
      return count_over<T>( 0, t );
    }
    
    for (auto i : count_upto(count))
    {
      // Do the stuff
    }
    

    indexer_t range_t 可以改进;它们都是最小的实现。

        4
  •  1
  •   eerorika    7 年前

    这是另一种选择。我不会宣布它比你自己的建议好或坏:

    for (auto i = 0 * count; i < count; i++) {
    

    请注意,正如在注释中提到的,在类型为 count 小于 int i

    也就是说,基于索引的循环通常可以(也许总是?)转换为基于迭代器的循环,其中 auto