4

我正在尝试实例化一组这样的字符串:

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 的方法。这可能吗?

4

2 回答 2

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

于 2015-09-07T08:10:03.303 回答
7

C++ 中的初始化器是定义的一部分,而不是声明的一部分。const这对于积分和enum类型来说是放松的。在 C++11 中,为文字类型constexpr的成员添加了更多指令

[class.static.data]/p3

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

由于它不适用于您的情况,因此您应该像本示例中所示那样初始化您的静态变量

class POI {
public:
  static const std::set<std::string> TYPES;
};

const std::set<std::string> POI::TYPES = {
   "restaurant", "education", "financial", "health", "culture", "other" 
};
于 2015-09-07T08:10:27.627 回答