2014-01-07 79 views
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顯示相同的行爲,所以我認爲這是一件我「米誤解。

回答

0

顯然是在未顯示main功能你沒有任何實例類。

那麼有沒有理由編譯器爲foo類的默認構造函數。

並且沒有,有沒有代碼實例reported_class<foo>

+0

添加了main()的樂趣正如你猜測的那樣,它不會實例化類。你的解釋聽起來似乎是合理的,但是在那種情況下,可以依賴reported_class 的實例化,還是編譯器可以在沒有任何對象構造的情況下自由地完全優化它? – kihlasht

+0

@kihlasht:我認爲不是因爲標準通常會爲了保持定義明確的副作用而痛苦,例如如果其構造函數或析構函數可能有副作用,則不允許將未使用的變量優化掉。但我不知道*。所以我建議你把它作爲一個新問題,如果它很重要的話(但是我個人而言,我寧願確保事情按我的意圖發生,而不是依賴於一個微妙的問題,人們必須問問專家,希望其中一個可能知道或花時間進行研究和分析,然後由墨菲定律編寫的某些編譯器肯定會錯誤地處理)。 –