草药销售商状态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()
,那么这种形式是否可以接受?
答案 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_t
和range_t
可以得到改进;它们都是最小的实现。
答案 3 :(得分:1)
这是另一种选择。我不会宣布它会比您自己的建议更好或更糟:
for (auto i = 0 * count; i < count; i++) {
请注意,如评论中所述,如果count
的类型小于int
,在这种情况下我的i
会得到晋升,这与您的行为有所不同。
也就是说,基于索引的循环通常可以(也许总是?)被转换为基于迭代器的循环,在这种情况下,auto
推导更为自然。