次のコードを取ります。
std::vector<std::vector<int>> v(10, 10);
このコードはlibstdc++ではコンパイルされません。ただし、VisualStudioのC++ライブラリでコンパイルされます。私が期待する動作はv
、サイズ10の10個のベクトルで満たされていることです。これは、VisualStudioで得られるものです。
Visual Studioで呼び出されるコンストラクターは、2つのイテレーターを使用するコンストラクターです。コンストラクター自体は次のように定義されます。
template<class _Iter>
vector(_Iter _First, _Iter _Last)
: _Mybase()
{ // construct from [_First, _Last)
_Construct(_First, _Last, _Iter_cat(_First));
}
テンプレート関数には2つのバージョンがあります_Construct
。どちらも同じシグニチャを持っていますが、一方は範囲からベクトルを初期化し、もう一方は2番目のパラメータから構築された値型copyのN個のコピーでベクトルを初期化します。この場合、テンプレートパラメータはの2番目のバージョンでのみ有効です_Construct
。
結果はv
、値10からコピー構築されたベクトルの10個のコピーで満たされます。libstdc++を使用して同じ効果を得るには、次のように構築することで同じコードパスが使用されます。
std::vector<int> temp(10);
std::vector<std::vector<int>> v(10, temp);
ここで正しい実装はどれですか?これはlibstdc++のバグですか、それともVisualStudioのC++ライブラリの拡張ですか?
編集:明確にするために、範囲コンストラクターを呼び出す必要があるかどうかは尋ねていません。私は、それを達成するためにどのパスをとるかに関係なく、どのC++実装が正しい動作をするかを尋ねています。