我有以下工作代碼:爲什麼我不能做一流初始化`常量常量的std :: string`靜態成員
#include <string>
#include <iostream>
class A {
public:
const std::string test = "42";
//static const std::string test = "42"; // fails
};
int main(void){
A a;
std::cout << a.test << '\n';
}
有一個很好的理由,不可能使測試一個static const
?我在C++ 11之前就明白它受到標準的約束。我認爲C++ 11引入了類內初始化,使它更友好一些。我也沒有這樣的語義可用於整型,因爲相當長的一段時間。
當然,它的工作原理與外的類的初始化在const std::string A::test = "42";
我想,如果你可以把它非靜態的,那麼問題就出在這兩個的一種形式。初始化它外的類範圍(通常const
s的對象的實例化期間創建的)。但是,如果你正在創建一個獨立於任何其他類的成員的對象,我認爲這不是問題。第二個是對靜態成員有多個定義。例如。如果它被包含在多個文件.cpp
,登陸成幾個對象的文件,然後連接這些物體一起(例如爲一個可執行文件)時,接頭將具有煩惱,因爲它們將包含相同的符號的副本。據我瞭解,這是完全相等的情況時,那些提供了課外權下的標題的類的聲明,幷包括一個以上的地方這個共同的頭。我記得,這導致鏈接器錯誤。
但是,現在將處理這個問題的責任轉移到用戶/程序員身上。如果想要有他們需要提供外的類的定義,它編譯成一個獨立的目標文件,然後將所有其他對象鏈接到這一個static
庫,因此具有二元的定義只有一個副本符號。
我在Do we still need to separately define static members, even if they are initialised inside the class definition?和Why can't I initialize non-const static member or static array in class?閱讀答案。
我還是想知道:
- 難道僅僅是一個標準的東西,還是有更深層次的推理背後?
- 這可以用
constexpr
和用戶定義的 文字機制來解決。 clang和g ++都表示變量不能有非文字類型。也許我可以做一個。 (也許由於某種原因,它也是一個壞主意) - 鏈接器是否真的有這麼大的問題只包含 符號的一個副本?既然是
static const
都應該是二進制精確 一成不變的副本。
如果我失蹤或誤解某事,Plese也會發表評論。那種
說到靜態,只能在聲明點初始化'const'整型和枚舉。 – juanchopanza
@juanchopanza我知道。我認爲在C++ 11中它可以被克服。 – luk32
我認爲你在3中指出了其中的一個問題。是的,這是可行的,但它需要這種情況下是特殊情況,否則鏈接器不會「喜歡」多個定義。 – ondrejdee