C ++ 11统一初始化:字段初始化器不是常量

时间:2015-09-07 07:47:10

标签: c++ c++11 uniform-initialization

我试图像这样实例化一组字符串:

class POI {
public:
...
  static const std::set<std::string> TYPES { "restaurant", "education", "financial", "health", "culture", "other" };
...
}

现在,当我这样做时,我得到了这些错误(全部都在这一行):

error: field initializer is not constant
 static const std::set<std::string> TYPES { "restaurant", "education", "financial", "health", "culture", "other" };
error: in-class initialization of static data member 'const std::set<std::basic_string<char> > POI::TYPES' of non-literal type
error: non-constant in-class initialization invalid for static member 'POI::TYPES'                                                              
error: (an out of class initialization is required)
error: 'POI::TYPES' cannot be initialized by a non-constant expression when being declared

如果我认为集合中的字符串不被视为const,那对我的眼睛来说是有意义的。这真的是问题吗?不幸的是,我找不到在初始化程序中将这些字符串声明为const的方法。这可能吗?

2 个答案:

答案 0 :(得分:8)

您必须在线外初始化静态变量,如:

#include <set>
#include <string>

class POI {
public:
  static const std::set<std::string> TYPES;
};
const std::set<std::string> POI::TYPES { "restaurant", "education", "financial", "health", "culture", "other" };

这适用于标准(第9.4.2节)

指定的整数/枚举类型
  

如果静态数据成员是const integral或const枚举类型,则它在类定义中的声明可以指定一个常量初始化器,它应该是一个整型常量表达式。在这种情况下,成员可以在其范围内出现在整数常量表达式中。

答案 1 :(得分:6)

C ++中的初始化程序应该是定义的一部分,而不是声明的一部分。对const积分和enum类型放宽了这一点。在C ++ 11中,为文字类型的<{1}}成员添加了进一步的指令

[class.static.data] / P3

  

如果非易失性const静态数据成员是整数或枚举类型,则其在类中声明   definition可以指定一个大括号或者相等的初始化程序,其中每个initializer子句都是赋值表达式   是一个常数表达式(5.20)。可以在。中声明文字类型的静态数据成员   使用constexpr说明符的类定义;如果是这样,其声明应指定一个支撑或等于初始化器   其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [......]该成员仍应定义   如果在程序中使用odr-used(3.2)并且命名空间作用域定义不在,则在命名空间作用域中   包含初始值设定项

由于它不适用于您的情况,因此您应该将您的静态变量初始化为行外as shown in this example

constexpr