#define for_all_impl(var, cont, mode) for (auto var##_begin_it = cont.##mode##begin(), var##_end_it = cont.##mode##end(), var##_it = var##_begin_it; var##_it != var##_end_it; ++var##_it) if (bool b = true) for (auto& var(*var##_it); b; b = false, var) if (bool b = true) for (const auto var##_num(var##_it - var##_begin_it); b; b = false, var##_num)
#define for_all(var, cont) for_all_impl(var, cont, )
#define for_all_const(var, cont) for_all_impl(var, cont, c)
#define for_all_reverse(var, cont) for_all_impl(var, cont, r)
#define for_all_const_reverse(var, cont) for_all_impl(var, cont, cr)
int main()
{
std::vector<int> a; a.push_back(0); a.push_back(1); a.push_back(2); a.push_back(3);
for_all(i, a)
{
std::cout << i_num << ": " << i << std::endl;
}
}
我之所以这样做是因为很长一段时间以来,C ++没有简单的快捷方式来迭代数据结构而无需大量输入。现在我们有了新的基于范围的for循环语法,但是没有简单的方法可以为您提供当前索引或向后(我知道)。
我花了很多时间设计它,所以请给它怀疑的好处,并指出任何重大缺陷。我假设只有常规变量名称将用作参数。我不是为所有人提出这个问题,但是从现在开始我将在我的项目中使用它,除非它有一个大问题。
感谢。
编辑:我意识到索引计数器(i_num)不适用于所有数据结构,例如列表。但我仍然觉得它很方便。
答案 0 :(得分:3)
不确定我喜欢这个。 if
条件没有相应的else
子句,因此循环体内的else
不会绑定到正确的if
和if
后面的else
许多else
条款不会导致错误。
您可以尝试使用then
子句而不是if
的{{1}}子句。 编辑:实际上,由于您只使用if
来引入变量,为什么不像其他地方那样使用for
?
您的宏也会影响我称之为b
的任何内容,这可能非常烦人。也许使用令牌粘贴来给出一个不太可能的名字?
答案 1 :(得分:2)
这是一个相当主观的问题,所以我的回答可能也是主观的。
通过使用这个宏,你实际上会创建一个C ++的方言,其他人通常不熟悉C ++,一开始就能读得舒服。对于您自己维护的项目而言,这不是问题,但在任何专业环境中,其他人将来必须阅读或更新您的代码,这是事实。您编写代码一次(这可能会节省少量编码),人们将在应用程序的生命周期内阅读它。出于这些原因,我建议不要使用宏。
另请注意,在许多情况下,诸如copy
(对流迭代器)和for_each
(可能与lambdas一起)等算法可以非常明确地执行您可能尝试使用for做的事情循环,并支持所有迭代方向,只需选择传入算法的迭代器。
答案 2 :(得分:0)
建议相同/类似功能的包装器。我所知道的社区维基只是一个概念,需要改进。
#include <iostream>
#include <vector>
template < typename Iter >
struct range
{
Iter m_begin;
Iter m_end;
struct Iterator// : std::iterator < ... >
{
Iter m;
Iter operator*() const
{ return m; }
bool operator!= (Iterator const& p) const
{ return m != p.m; }
Iterator& operator++()
{ ++m; return *this; }
};
Iterator begin()
{
return Iterator{m_begin};
}
Iterator end()
{
return Iterator{m_end};
}
};
template < typename Cont >
range < typename Cont::iterator > make_range(Cont& p)
{ return {p.begin(), p.end()}; }
template < typename Cont >
range < typename Cont::reverse_iterator > make_reverse_range(Cont& p)
{ return {p.rbegin(), p.rend()}; }
int main()
{
std::vector<int> v = {1,2,3,4,5};
for(auto it : make_reverse_range(v))
{
auto var = *it;
std::cout << var << std::endl;
}
}