1
我想弄清楚鏗鏘如何確定什麼C++模板靜態成員變量需要實例化,我看到一些讓我困惑的行爲。模板靜態成員變量的實例化
考慮下面的代碼:
#include <stdio.h>
#include <typeinfo>
int report(const char *name)
{
printf("Reporting class: %s\n", name);
return 0;
}
template<typename ReportedClass>
class reported_class
{
public:
reported_class()
{
_reported_instances++;
}
private:
static int _reported_instances;
};
template<typename ReportedClass>
int reported_class<ReportedClass>::_reported_instances = report(typeid(ReportedClass).name());
class foo : reported_class<foo>
{
public:
int baz() { return 0; }
};
class bar : reported_class<bar>
{
public:
bar() { }
int baz() { return 0; }
};
int main(int argc, char **argv)
{
return 0;
}
當我運行它,我看到以下內容:
$ c++ -v
Apple LLVM version 5.0 (clang-500.0.68) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
$ c++ test.cpp
$ ./a.out
Reporting class: 3bar
$
爲什麼對reported_class靜態被實例化,但不是一個foo的?唯一的區別似乎是存在一個構造函數,但我期望在任何一種情況下調用reported_class構造函數(因此在構造函數中使用靜態實例化)。標準中是否有這個原因,我不知道,這是可以依賴的嗎?
GCC-4.7.3顯示相同的行爲,所以我認爲這是一件我「米誤解。
添加了main()的樂趣正如你猜測的那樣,它不會實例化類。你的解釋聽起來似乎是合理的,但是在那種情況下,可以依賴reported_class的實例化,還是編譯器可以在沒有任何對象構造的情況下自由地完全優化它? –
kihlasht
@kihlasht:我認爲不是因爲標準通常會爲了保持定義明確的副作用而痛苦,例如如果其構造函數或析構函數可能有副作用,則不允許將未使用的變量優化掉。但我不知道*。所以我建議你把它作爲一個新問題,如果它很重要的話(但是我個人而言,我寧願確保事情按我的意圖發生,而不是依賴於一個微妙的問題,人們必須問問專家,希望其中一個可能知道或花時間進行研究和分析,然後由墨菲定律編寫的某些編譯器肯定會錯誤地處理)。 –