初始化在类的私有成员中声明的静态容器数据

时间:2012-06-27 23:14:02

标签: c++ vector static containers

我有一个私有成员(struct)的课程如下:

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

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

然后,在实现中,我在结构中定义了一个静态容器(vector),如下所示:

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

其他信息:

当我尝试在实现中初始化它时,但在struct和任何类成员之外(以及在设置向量大小的赋值之后)如下所示:

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的构造函数中(似乎是一个自然的地方)。此外,如果我尝试将容器设为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容器做同样的事情?一如既往地欣赏任何想法和想法。谢谢!

1 个答案:

答案 0 :(得分:1)

  

我初始化静态容器的位置是否合适?

是的,类的静态数据成员需要在命名空间范围内定义。但是这些

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

是表达式,在全局范围内不允许使用它们。编译器试图将它们解析为声明,因此错误:“无法分配常量大小为0的数组”。您需要在成员函数中移动此逻辑。

  

如果在分配p_impl之前移动了v的初始化,是否会导致运行时错误?换句话说,是否存在将内存分配给静态成员的顺序?

静态成员具有外部链接,因此保证在main()启动之前完全构造它们。

  

另外,如何使我的容器成为静态const而不会遇到下面描述的错误?

您只能初始化const变量,而不能在以后更改。在C ++ 11中,你可以做到

std::vector<std::string> myclass::impl::v = { str0, str1, str2, ... };