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

C++11 uniform initialization: Field initializer is not constant

本文关键字:初始化 常量 字段 c++      更新时间:2023-10-16

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

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

如果假定set中的字符串不被视为const,那么在我看来这是有意义的。这真的是问题所在吗?不幸的是,我无法找到在初始化式中将这些字符串声明为const的方法。这可能吗?

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

#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整型或const枚举类型,则在类定义中声明它可以指定一个常量初始化式,该常量初始化式应为整型常量表达式。在这种情况下,成员可以出现在其作用域内的整型常量表达式中。

c++中的初始化式应该是定义的一部分,而不是声明的一部分。这对于const积分型和enum积分型是宽松的。在c++ 11中,为字面值

constexpr成员添加了进一步的指令。

[class.static.data]/p3

如果非易失性const静态数据成员是整型或枚举类型,则在类中声明定义可以指定一个大括号或等号初始化项,其中每个初始化项子句都是赋值表达式是常量表达式(5.20)。类中声明文字类型的静态数据成员用constexpr说明符定义类;如果是,它的声明应该指定一个大括号或等号初始化式其中,每个赋值表达式的初始化子句都是常量表达式。[…成员仍需定义在一个命名空间作用域中,如果它在程序中被odr(3.2)使用,并且命名空间作用域定义不允许使用包含初始化式

由于它不适用于您的情况,因此您应该初始化您的静态变量out- line,如下例

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