几乎总是自动的,并带有计数器的循环

时间:2018-08-30 15:33:29

标签: c++ c++11

草药销售商状态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()永远不会返回浮点数),而无需对{{1} }并避免出现诸如“有符号-无符号”不匹配之类的编译警告。

我的问题是:假设将来可能会重新定义get_count(),那么这种形式是否可以接受?

4 个答案:

答案 0 :(得分:4)

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

#include <boost/range/irange.hpp>

for(auto i : boost::irange(get_count()))

在{1.63中引入了boost::irange的单参数版本,因此您需要复制implementation以用于早期版本。

答案 1 :(得分:3)

要成为AAA,您可以转到:

for (auto i = decltype(count){}; i != count; ++i) { /*..*/ }

答案 2 :(得分:2)

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_trange_t可以得到改进;它们都是最小的实现。

答案 3 :(得分:1)

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

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

请注意,如评论中所述,如果count的类型小于int,在这种情况下我的i会得到晋升,这与您的行为有所不同。

也就是说,基于索引的循环通常可以(也许总是?)被转换为基于迭代器的循环,在这种情况下,auto推导更为自然。