3
所以說我有一個位的代碼輸出下面很簡單的宏,沿着它:C++恆預處理宏和模板
#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
std::cout << SIMPLEHASH("Blah");
這個輸出309,如果你查看裝配就可以看到:
00131094 mov ecx,dword ptr [__imp_std::cout (132050h)]
0013109A push 135h
0013109F call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (13203Ch)]
其中135h
很好地翻譯成309十進制。一切都被編成了一個常數。
現在,假設你有一個模板類這樣:
template<int X> class Printer{
public:
void Print(){
std::cout << X;
}
};
那麼下面將很好地打印數32:這兩個東西單獨工作
Printer<32> p;
p.Print();
,當您嘗試將它們合併時,問題就出現了:
#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
Printer<SIMPLEHASH("Blah")> p;
p.Print();
在Visual Studio這給出:
1> \ ShiftCompare.cpp(187):錯誤C2975: 'X':爲 '打印機' 無效模板參數,預期編譯時間常量表達式
1> \ ShiftCompare.cpp(127):參見「X」
的聲明儘管SIMPLEHASH("Blah")
可以降低到在編譯時的常數,如在第一實施例所示。
那麼,有什麼辦法可以告訴編譯器「先評估這個」?模板在預處理器評估中自然地位於「宏」之前?
有沒有人看到任何方式我可以讓這兩個一起工作?
預處理器是一個紅色的鯡魚。根據該語言,「Blah」[0]不是一個常量表達式;而已。僅僅因爲你的編譯器偶然發現並不意味着什麼。 (這是針對特定實現的結果的問題,並且假設它是由語言保證的。) – GManNickG 2010-10-15 22:33:35
回答「我怎樣才能讓這兩個人一起工作?」部分,如果你能解釋你正在試圖解決的實際問題,這將是有幫助的。如果你無法一起獲得這兩件事情,那麼你可以通過其他方式解決你的問題。 – 2010-10-15 22:35:48
試圖讓hashing函數在工廠類中創建別名(在編譯時)以進行註冊。我試圖給需要註冊的類是一個靜態(模板類)成員s.t.該成員可以在構造函數被調用時將其註冊爲擁有類(靜態,立即在代碼加載時)。顯而易見的另一種方式是使用全局變量而不是靜態成員,而且工作正常,我只是想看看是否有一種方法不會讓全局變量在命名空間中飛行。 – Jason 2010-10-15 23:13:24