几乎总是自动和带计数器的循环
Almost Always Auto and for loops with counter
Herb Sutter 状态几乎总是自动的,我有以下代码:
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()
永远不会返回浮点数(,而无需对函数get_count()
客户端代码进行任何修改,并避免编译警告,如"有符号-无符号"不匹配。
我的问题是:假设count_t
将来可能会被重新定义,这种形式是否可以接受?
如果可以选择使用Boost,则可以避免所有噪音
#include <boost/range/irange.hpp>
for(auto i : boost::irange(get_count()))
boost::irange
的单参数版本是在 1.68 中引入的,因此您需要复制早期版本的实现。
要仍然是 AAA,您可以转到:
for (auto i = decltype(count){}; i != count; ++i) { /*..*/ }
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
可以改进;它们都是最小的实现。
这是另一种选择。我不会宣布它比你自己的建议更好或更差:
for (auto i = 0 * count; i < count; i++) {
请注意,如评论中所述,在count
类型小于int
的情况下,这与您的行为不同,在这种情况下,我的i
被提升。
也就是说,基于索引的循环通常(也许总是?(可以转换为基于迭代器的循环,其中auto
推导更自然。
相关文章:
- 循环在计数器中不起作用
- C++ 在循环中添加计数器变量并再次初始化其值
- 几乎总是自动和带计数器的循环
- 为什么使用 2 个嵌套循环 O(n^2) 复杂度来解决二和问题,当只改变循环计数器逻辑时运行得更快?
- 对于循环计数器不递增
- 如何在C++中创建 2d 数组,其中一部分包含循环计数器,另一部分包含数字列表?
- 当输出达到某个值时,如何在 c++ 中中断计数器循环
- 如何在C++中使用带有"do while"循环的计数器?
- 而循环计数器不递增
- 在 Rust 中捕获循环计数器副本的函数
- 为什么它不是一个不确定的循环,因为循环计数器在整数变量的范围之外
- 当我在do-while循环c++中使用计数器时,字母被截断了
- 带有计数器的循环的 CUDA 索引
- 增加OpenMP中用于进度报告的共享循环计数器
- 使用计数器控制while循环
- 用于循环计数器失败的 C++
- 在 for 循环中声明几个新计数器
- For 循环是覆盖循环计数器
- 使用 for 循环中的计数器作为条件
- 对于 C++ 中的每个计数器循环不会以特定数字递增