1. ホーム
  2. c++

[解決済み】forループで型の異なる2つの変数を宣言することは可能ですか?

2022-03-31 11:48:19

質問

C++のforループの初期化本体で、型の異なる2つの変数を宣言することは可能でしょうか?

例えば

for(int i=0,j=0 ...

は2つの整数を定義しています。を定義することはできますか? intchar を初期化ボディの中に入れることができますか?これはどのように行われるのでしょうか?

どのように解決するのですか?

C++17 : Yes! を使用する必要があります。 構造化バインディング宣言 . この構文は gcc-7 と clang-4.0 以降、gcc と clang でサポートされています ( clang ライブサンプル ). これにより、次のようにタプルを展開することができます。

for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"ab"}}; i < N; ++i, f += 1.5) {
    // ...
}

上記で得られます。

  • int i に設定します。 1
  • double f に設定します。 1.0
  • std::string s に設定します。 "ab"

を確認してください。 #include <tuple> のような宣言が必要です。

の内部で正確な型を指定することができます。 tuple と同じように、すべて入力することで std::string , タイプに名前を付けたい場合。例えば

auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}

具体的な応用例としては、マップを反復処理し、キーと値を取得することが挙げられます。

std::unordered_map<K, V> m = { /*...*/ };
for (auto& [key, value] : m) {
   // ...
}

実例を見る こちら


C++14 : C++11(以下略)と同じように、タイプベースの std::get . そのため std::get<0>(t) を使用すると、以下の例のようになります。 std::get<int>(t) .


C++11 : std::make_pair では、このようなことができるほか std::make_tuple を2つ以上のオブジェクトのために使用します。

for (auto p = std::make_pair(5, std::string("Hello World")); p.first < 10; ++p.first) {
    std::cout << p.second << '\n';
}

std::make_pair は、2つの引数を std::pair . この要素にアクセスするには .first.second .

2つ以上のオブジェクトを使う場合は std::tuple

for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
        std::get<0>(t) < 10;
        ++std::get<0>(t)) {
    std::cout << std::get<1>(t) << '\n'; // cout Hello world
    std::get<2>(t).push_back(std::get<0>(t)); // add counter value to the vector
}

std::make_tuple は、任意の数の引数のタプルを構築するバリアドテンプレートです(もちろん、いくつかの技術的な制限はあります)。 この要素には std::get<INDEX>(tuple_object)

for ループのボディでは、オブジェクトのエイリアスを簡単に作成することができます。 .first または std::get は、for ループの条件と更新式です。

for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
        std::get<0>(t) < 10;
        ++std::get<0>(t)) {
    auto& i = std::get<0>(t);
    auto& s = std::get<1>(t);
    auto& v = std::get<2>(t);
    std::cout << s << '\n'; // cout Hello world
    v.push_back(i); // add counter value to the vector
}


C++98とC++03 の型に明示的に名前を付けることができます。 std::pair . しかし、これを2つ以上の型に一般化する標準的な方法はありません。

for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
    std::cout << p.second << '\n';
}