0

私は次のようにプライベートメンバー()を持つクラスを持ってstructいます:

enum indices {
   zero,
   one, 
   two,
   ...,
   N
};

class myclass {
  ...
  ...
private: 
  struct impl;
  impl* p_impl;
};

次に、実装では、構造体に静的コンテナ(ベクトル)を次のように定義しました。

struct myclass::impl {
   impl() : ... {
      ...
      do_something;
      ...
   }
   ...
   ...
   static std::vector<std::string> v;
   ...
};

std::vector<std::string> myclass::impl::v = std::vector<std::string>(N); //-N is defined by an enum, say.


myclass::myclass() {
    p_impl = new impl();
    //-Is this where I should populate the static container?
    impl::v[zero] = str0;
    impl::v[one] = str1;
    ...
    impl::v[N] = strN;
}

... 

私の質問は次のとおりです。静的コンテナを初期化した場所は適切ですか?v割り当てる前にの初期化を移動した場合p_impl、実行時エラーが発生しますか?つまり、静的メンバーにメモリが割り当てられる順序はありますか?static constまた、以下に説明するエラーが発生しないようにコンテナを作成するにはどうすればよいですか?

追加情報:

実装で初期化しようとしたが、構造体とクラスメンバーの外で(そしてベクトルのサイズを設定する代入の後)次のようにしたとき:

std::vector<std::string> myclass::impl::v = std::vector<std::string>(N); //-N is defined by an enum, say.
myclass::impl::v[zero] = str0;
myclass::impl::v[one] = str1;
...
myclass::impl::v[N] = strN;

次に、Windows(VC ++ 2008)でビルドエラーが発生します。

error C2466: cannot allocate an array of constant size 0

これにより、初期化をのコンストラクターに配置myclassすることになりました(自然な場所のようです)。さらに、コンテナをaにしようとすると、static const次のようにすべてがエラーで壊れます。

 error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::basic_string<_Elem,_Traits,_Ax>' (or there is no acceptable conversion)
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>,
            _Ax=std::allocator<char>
        ]
        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xstring(914): could be 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const std::basic_string<_Elem,_Traits,_Ax> &)'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>,
            _Ax=std::allocator<char>
        ]
        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xstring(919): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const _Elem *)'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>,
            _Ax=std::allocator<char>
        ]
        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xstring(924): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(_Elem)'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>,
            _Ax=std::allocator<char>
        ]
        while trying to match the argument list '(const std::basic_string<_Elem,_Traits,_Ax>, const std::string)'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>,
            _Ax=std::allocator<char>
        ]

static constコンテナで同じことをする例はありますか?いつものように考えやアイデアに感謝します。ありがとう!

4

1 に答える 1

1

静的コンテナを初期化した場所は適切ですか?

はい、クラスの静的データメンバーには名前空間スコープでの定義が必要です。しかし、これらは

myclass::impl::v[zero] = str0;
myclass::impl::v[one] = str1;
...
myclass::impl::v[N] = strN;

式であり、グローバルスコープでは許可されていません。コンパイラはそれらを宣言として解析しようとしているため、「定数サイズ0の配列を割り当てることができません」というエラーが発生します。このロジックをメンバー関数で移動する必要があります。

p_implを割り当てる前にvの初期化を移動した場合、実行時エラーが発生しますか?つまり、静的メンバーにメモリが割り当てられる順序はありますか?

静的メンバーには外部リンケージがあるため、main()が開始する前に完全に構​​築されることが保証されます。

また、以下に説明するエラーが発生することなく、コンテナを静的定数にするにはどうすればよいですか?

const変数を初期化することはできますが、後で変更することはできません。C++11では次のことができます

std::vector<std::string> myclass::impl::v = { str0, str1, str2, ... };
于 2012-06-27T23:21:27.650 に答える