list
と呼ばれる_std::initializer_list
_を受け入れる関数を作成していて、その関数がlist
の要素へのランダムアクセスを必要としているとします。 list.begin()[i]
の代わりに_list[i]
_を書くと便利です。では、なぜ_std::initializer_list
_は_operator[]
_の定義を提供しないのですか?
_operator[]
_が_const T&
_を返すことが明確に定義されていない場合は考えられません。 _std::initializer_list<T>::iterator
_は明らかにランダムアクセスイテレータである_const T*
_にエイリアスされているため、ここでは効率は問題ではないようです。
C++プログラミング言語、第4版のセクション17.3.4.2(p。497)のBjarne Stroustrupによると、
残念ながら、initializer_listは添え字を提供しません。
それ以上の理由は与えられていません。
私の推測では、これは次の理由の1つです。
2と4の音は弱い。 3.私のお金は1にあります。
特定のインデックスにランダムに直接アクセスする必要があるのは妥当なシナリオであるため、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
は繰り返し作成されます。もちろん、これはなぜこれが規格自体によって提供されなかったのか不思議を引き起こします。