web-dev-qa-db-ja.com

`std :: initializer_list`が下付き演算子を提供しないのはなぜですか?

listと呼ばれる_std::initializer_list_を受け入れる関数を作成していて、その関数がlistの要素へのランダムアクセスを必要としているとします。 list.begin()[i]の代わりに_list[i]_を書くと便利です。では、なぜ_std::initializer_list_は_operator[]_の定義を提供しないのですか?

_operator[]_が_const T&_を返すことが明確に定義されていない場合は考えられません。 _std::initializer_list<T>::iterator_は明らかにランダムアクセスイテレータである_const T*_にエイリアスされているため、ここでは効率は問題ではないようです。

39
void-pointer

C++プログラミング言語、第4版のセクション17.3.4.2(p。497)のBjarne Stroustrupによると、

残念ながら、initializer_listは添え字を提供しません。

それ以上の理由は与えられていません。

私の推測では、これは次の理由の1つです。

  1. それは省略です、または
  2. initializer_listクラスは配列で実装されており、安全なアクセスを提供するために境界チェックを行う必要があるため、そのインターフェースが提供されている場合は、より安全に安全に使用できません。
  3. stdアルゴリズムの反復パラダイムと一致するようにする、または
  4. initializer_listsは、その性質上、アドホックであるため、直接アドレス指定することにより、エラーが発生する余地があります。

2と4の音は弱い。 3.私のお金は1にあります。

11
Homer6

特定のインデックスにランダムに直接アクセスする必要があるのは妥当なシナリオであるため、std :: initializer_listに角かっこ演算子がないのは、確かに少し面倒です。

ただし、この機能はいくつかの簡単なコードで追加できます。

// the class _init_list_with_square_brackets provides [] for initializer_list
template<class T>
struct _init_list_with_square_brackets {
    const std::initializer_list<T>& list;
    _init_list_with_square_brackets(const std::initializer_list<T>& _list): list(_list) {}
    T operator[](unsigned int index) {
        return *(list.begin() + index);
    } 
};

// a function, with the short name _ (underscore) for creating 
// the _init_list_with_square_brackets out of a "regular" std::initializer_list
template<class T>
_init_list_with_square_brackets<T> _(const std::initializer_list<T>& list) {
    return _init_list_with_square_brackets<T>(list);
}

これで、_(アンダースコア)という名前の新しいグローバル関数ができました。これは、C++用の「アンダースコアのような」ユーティリティライブラリを作成する場合を除いて、おそらくグローバルC++メソッドの適切な名前ではありません。 _その他のあらゆる便利な使用法のための関数。

新しい_関数は次のように使用できます。

void f(std::initializer_list<int> list) {
    cout << _(list)[2]; // subscript-like syntax for std::initializer_list!
}

int main() {
    f({1,2,3}); // prints: 3
    cout << _({1,2,3})[2]; // works also, prints: 3
    return 0;
}

上記の提案されたタイプの一時オブジェクトとしてstd :: initializer_listの多くの項目を実行する場合、上記のソリューションはパフォーマンスの面でお買い得ではないことに注意してください_init_list_with_square_bracketsは繰り返し作成されます。もちろん、これはなぜこれが規格自体によって提供されなかったのか不思議を引き起こします。

3
Amir Kirsh