1

組み合わせを見つけるには、同じコンテナ上で2つのループが必要です。

the first iterates over elements:
  pick an element
  iterate over the elements on the left
    print the first and the second iterated elements

だからここに間違った例があります:

vector<int> vec;
for(size_t i=0; i< 10 ; ++i) vec.push_back(i);
for(auto i : vec)
{
  auto j = i.increaseBy(1);
  for(j : vec) cout << i << j << "\n";
}

この質問では、要素を反復処理する単純な方法だけでなく、範囲ループの構文にもっと多くのものがあるかどうかに興味があります。c++11に関するドキュメントはあまりありません。

4

2 に答える 2

7

(リスト内包表記構文を使用した擬似コードを使用して)反復する場合[(v[i], v[j]) | i <- [0..v.size()], j <- [0..i]]は、Boost.Rangeの助けを借りて次のことを行うことができます。

for(auto i: boost::irange(0, v.size()))
    for(auto j: boost::irange(0, i)) {
        // use v[i] and v[j]
    }

ただし、例を超えて、あなたの質問に対する答えは、いいえ、range-forステートメントはあまり魔法をかけないということです。また、拡張可能ではありません。ただし、良いニュースは、それを見る別の方法があることです。range-forステートメントはかなり馬鹿げているかもしれませんが、範囲は必要に応じて賢くすることができます。

つまり、range-forは範囲の要素に対してのみ反復できる可能性がありますが、その範囲には、たとえば、期待しているように見えるものとは異なり、実際の既存のコンテナーにマップする必要はありません。たとえば、これ

namespace A = boost::adaptors;
for(auto&& e: A::strided(v, 2)) foo(e);

fooのその他すべての要素を呼び出しますv。ここでの作業はstrided、range-forステートメントではなく、によって行われます。

Boost.Rangeを使用しても、1つの範囲で例を簡潔に表現する方法は考えられません。しかし、それが不可能であるという意味ではありません。私は過去にC++で何らかの形式のリスト内包表記を調査しました。しかし、それを表現するためのツールは今日ここにはありません。

于 2012-09-19T15:07:13.077 に答える
5

あなたが求めているのは、ベクトル要素のペアのコレクションだと思います。

これは、範囲ベースのループの目的ではありません。範囲ベースのループは、コレクション全体を反復処理し、各要素を1回だけ確認するためのものです。それらを他の目的に使用しないでください。それが新しく追加された言語機能であるという理由だけで、あなたが今まで知っていた他のすべてを捨てなければならないという意味ではありません。新しい機能は言語を豊かにします、彼らはそれを置き換えません。

一意のペアを取得する方法は次のとおりです。

for (auto it1 = vec.begin(), end = vec.end(); it1 != end; ++it1)
{
     for (auto it2 = std::next(it1); it2 != end; ++it2)
     {
         std::cout << "[" << *it1 << ", " << *it2 << "]\n";
     }
}

対角要素()も含める場合はit1, it1、2番目の初期化を。に置き換えるだけauto it2 = it1です。

于 2012-09-19T15:00:00.977 に答える