2015-09-07 124 views
4

我试图实例化这样一组字符串:C++ 11均匀初始化:字段初始化不恒定

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声明在初始化程序中。这可能吗?

+5

NSDMI并不适用于静态成员 –

+1

这就是N代表:-)(** N ** *上* S ** tatic ** D ** ata ** M ** ember ** I ** nitializer)。 – Jarod42

回答

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

6

C++中的初始化器意味着成为定义的一部分,而不是声明的一部分。这是放宽const积分和enum类型。在C++ 11个进一步指示为文本类型的constexpr成员加入

[class.static.data]/P3

如果非易失性const的静态数据成员是积分或枚举类型时,其类 定义中的声明可以指定一个括号或等于初始值设定项,其中每个作为赋值表达式 的初始化子句都是常量表达式(5.20)。可以在类定义中使用constexpr说明符在 中声明文字类型的静态数据成员;如果是,则其声明应指定一个括号或等号初始化程序 ,其中每个作为赋值表达式的初始化子句都是一个常量表达式。 [...]的构件,仍可以在命名空间范围限定 如果在程序ODR使用(3.2)和命名空间范围定义不应 包含一个初始化

,因为它不适用于你的情况,你应该这样初始化你的静态变量外的线as shown in this example

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

const std::set<std::string> POI::TYPES = { 
    "restaurant", "education", "financial", "health", "culture", "other" 
}; 
+0

1)对于文字类型,它是'constexpr',而不是'const'。 2)使用'constexpr',实际上需要一个课内初始化器。 –

+0

谢谢,编辑了这一行。 –