3
#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) が機能しないことを認識しています。でもやっぱり便利だと思います。

4

3 に答える 3

3

私はこれが好きかどうかわかりません。if条件には対応する句がないためelseelseループ本体内の s は正しいものにバインドされずififその後にelse句が多すぎてもエラーは発生しません。

the節elseではなく、 節を使用してみてください。 編集:実際には、変数を導入するためにのみ s を使用するので、他の場所で行ったように代わりに使用してみませんか?thenififfor

あなたのマクロは、私が呼び出したものもb隠します。これは非常に面倒です。たぶん、トークンの貼り付けを使用して、あまりありそうもない名前を付けますか?

于 2013-05-10T22:55:19.430 に答える
2

これはかなり主観的な質問なので、私の答えもおそらく主観的なものになるでしょう。

このマクロを使用することで、通常 C++ に堪能な他の誰も最初は快適に読めないような C++ の方言を効果的に作成できます。これは、自分で管理するプロジェクトでは問題になりませんが、プロフェッショナルな環境では、将来誰かがあなたのコードを読んだり更新したりする必要があるのは現実です。コードを 1 回記述すると (これにより、少量のコーディングを節約できる可能性があります)、人々はアプリケーションの存続期間中そのコードを読むことになります。このような理由から、マクロを使用しないことをお勧めします。

また、多くの場合、copy(ストリーム イテレータに対して) やfor_each(おそらくラムダと組み合わせて) などのアルゴリズムは、for ループで実行しようとすることを非常に表現力豊かに行うことができ、どの方向を選択するかだけで反復のすべての方向をサポートできることに注意してください。アルゴリズムに渡す反復子。

于 2013-05-10T23:11:25.377 に答える
0

同じ/類似の機能のラッパーを提案します。私が知っているように、コミュニティ wiki は単なる概念であり、改善が必要です。

#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;
    }
}
于 2013-05-11T01:01:40.367 に答える