2015-09-07 136 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

謝謝,編輯了這一行。 –