3

次のコードを取ります。

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++実装が正しい動作をするかを尋ねています。

4

2 に答える 2

3
std::vector<std::vector<int>> v(10, 10);

ベクトルの単一引数コンストラクターは明示的であるため、これはコンパイルしないでください。

C ++ 03:

explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());

C ++ 11:

explicit vector(size_type n);

これは、10のような数値が暗黙的にサイズ10のベクトルに変換できないことを意味します。

于 2011-10-08T23:18:18.730 に答える
0

私が期待する動作は、vがサイズ10の10個のベクトルで満たされていることです。

これはまさにGCC/libstdc++4.1.2で起こることです。_Constructと呼ばれるものは

void std::_Construct<std::vector<int>, int>(std::vector<int>*, int const&)

(アロケータを省略)。規格がこれについて何を言っているかはわかりませんが、私の勘は、それは古いGCC /libstdc++のバグだということです。

于 2011-10-08T22:21:00.983 に答える