1

問題はこのバグに似ています

C++のstd::vectorに配列を格納することに関する質問

しかし、別の理由で(以下を参照)。

C ++の次のサンプルプログラムの場合:

#include <vector>

int main(int c_, char ** v_)
{
        const int LENGTH = 100;

        std::vector<char[LENGTH]> ca_vector;

        return 0;

}

GCC4.2.3はきれいにコンパイルされます。GCC 4.3.2は、次のエラーを発行します。

/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:関数内'void std :: _ Destroy(_Tp *)[with _Tp = char [100 ]]':
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:103:'void std :: _ Destroy(_ForwardIterator、_ForwardIterator)[with _ForwardIterator = char(*)[100]] '
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:128:'void std :: _ Destroy(_ForwardIterator、_ForwardIterator、std :: allocator&からインスタンス化)[with _ForwardIterator = char(*)[100]、_Tp = char [100]] '
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_vector.h:300:'std :: vector ::〜vector()からインスタンス化[with _Tp = char [100]、_ Alloc = std :: allocator] '
test.cpp:7:ここからインスタンス化
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:88:エラー:'*__pointer'のメンバー'〜char[100]'のリクエスト、非クラスタイプ'char[100]'

理由はどうやらこのビットにあります

include / g ++-v4 / bits / stl_construct.h

  template
    inline void
    _Destroy(_Tp* __pointer)
    { __pointer->~_Tp(); }

これは、配列からポインタへの減衰が正しくないために呼び出されると思います。

私の質問は: std :: vectorでの配列の保存を妨げる言語標準に何かありますか?それとも、その特別なGCCバージョンの単なるバグですか?

私はこれがコンパイルされるべきだと信じています(つまり4.2.3が正しい)。

ありがとうマーティン

4

4 に答える 4

6

はい、標準には、ドラフトC++98標準を使用した配列の使用を停止する何かがあります。

セクション23コンテナ

これらのコンポーネントに格納されているオブジェクトのタイプは、CopyConstructibleタイプ(20.1.3)の要件、およびAssignabletypesの追加要件を満たしている必要があります。

コンポーネントがさまざまなコンテナである場合

20.1.3には、タイプにデストラクタが必要であるという要件が含まれています。

ベクトルは、要素の割り当てと削除をコピーする必要があると思います。C++はchar[]をコピーまたは削除することをどのように知っていますか?

于 2009-10-13T12:15:59.687 に答える
2

いいえ、これは許可されていません。リンク先の質問で許可されていなかったのと同じです(「理由が違う」のかわかりません)。これは、2つの質問のどちらでも「バグ」ではありません。または、少なくとも、コンパイラのバグではありません。ちょうどあなたのコードで。;)

ベクトルにはその要素がコピー構築可能で割り当て可能である必要があるため、配列をベクトルに格納することはできません。

于 2009-10-13T12:42:03.357 に答える
2

これを行う最も簡単な解決策は次のとおりです。

std::vector<boost::array<LENGTH> > ca_vector;

このようにして、配列/ポインターの話に煩わされる必要はありません。あなたが本当にこれを望んでいるかどうかは別問題です。

于 2009-10-13T12:46:56.377 に答える
-1

このコードの意図を教えてください。ベクトルもある種の配列であり、初期サイズを指定する必要はありません。

1D vector  ->  std::vector<char*> ca_vector;
2D vector  ->  std::vector<char*,char*> ca_vector;
于 2009-10-13T12:25:49.983 に答える