4

私は C++11 に非常に慣れていないので、反復子と一様な初期化に問題があり、理解できません。

コンパイルされない次の例を考えてみましょう。

#include <iostream>
#include <vector>

int main() {

    std::vector<int> t{1, 2, 3, 4, 5};
    auto iter{t.begin()};                   

    for (; iter != t.end(); ++iter) {
        std::cout << *iter;
    }

    return 0;
}

6 行目では、均一な初期化を使用してベクトルが初期化されます。7 行目では、イテレータで同じことをしようとしています。それは動作しません。7 行目を変更してauto iter = t.begin()も問題ありません。これには単に「範囲ベース」を使用できることはわかっていますが、問題は、イテレータでは一様な初期化が機能しないのに、のような基本型では問題ないのはなぜint i{0};ですか?

4

2 に答える 2

4

で初期化子として initializer-list を使用するとauto、宣言された変数は初期化子リストとして推定されます。つまり、iterは として宣言されておりstd::initializer_list<vector<int>::iterator>vector<int>::iterator予想とは異なります。

に変更するauto iter = t.begin()のが最善の方法です。

于 2014-06-15T20:28:07.630 に答える
3

C++11 には、autoと推論される波括弧付きの初期化のための特別な規則がありますstd::initializer_list。あなたの場合、選択肢は次のいずれかです。

auto iter(t.begin());
auto iter = t.begin();

動作は次の場所で説明されています。

§7.1.6.4/7auto指定子 [dcl.spec.auto]

T を変数の宣言された型または関数の戻り値の型とします。プレースホルダーが auto 型指定子である場合、推定される型は、テンプレート引数推定の規則を使用して決定されます。演繹が return ステートメントに対するものであり、初期化子が波括弧初期化リスト (8.5.4) である場合、プログラムは不正な形式です。それ以外の場合は、auto の出現箇所を新しい発明された型テンプレート パラメーター Uに置き換えるか、初期化子が波括弧初期化リストの場合は std::initializer_-list に置き換えることで、T から P を取得します。. 関数呼び出し (14.8.2.1) からのテンプレート引数推定の規則を使用して、U の値を推定します。ここで、P は関数テンプレート パラメーターの型であり、初期化子は対応する引数です。控除が失敗した場合、宣言は不適切な形式です。それ以外の場合、変数または戻り値の型に対して推定される型は、推定される U を P に代入することによって取得されます。

(強調鉱山)。

Scott Meyer は最近、まさにこの問題についての講演を行いました。ビデオを見ることをお勧めします。

于 2014-06-15T20:27:58.563 に答える