2010-05-25 105 views
6

是否可以在預處理器指令中使用非類型常量模板參數?下面是我的想法:在預處理器指令中使用模板參數嗎?

template <int DING> 
struct Foo 
{ 
    enum { DOO = DING }; 
}; 

template <typename T> 
struct Blah 
{ 
    void DoIt() 
    { 
     #if (T::DOO & 0x010) 

     // some code here 

     #endif 
    } 
}; 

當我嘗試這樣的東西,如Blah<Foo<0xFFFF>>,VC++ 2010抱怨一些關於該行括號不匹配,我們正在嘗試使用#if。我猜測預處理器並不知道任何關於模板的事情,而這種事情不在其領域內。說啥?

+0

只是一個點要注意的:'胡說>'不會在當前的C解析++,你需要'>'s之間的空間。 'Blah >'。 – KitsuneYMG 2010-05-25 12:30:59

+0

實際上,在VC++ 2010中它編譯! :)他們在VC++ 2010中部分實現了C++ 0x。 – Raj 2010-05-25 13:21:58

回答

11

不,這是不可能的。預處理器非常笨,並且它不知道程序的結構。如果T::Doo未在預處理器中定義(並且由於::而不能定義),它不能評估該表達式並且會失敗。

但是,你可以依靠編譯器做聰明的事情你:

 if (T::Doo & 0x010) { 
      // some code here 
     } 

常量表達式和枯枝甚至在較低的優化設置優化掉,所以你可以放心地做到這一點沒有任何運行時開銷。

+0

如果'Doo'不存在於'T'中,這不會無法編譯嗎? – 2010-05-25 12:40:51

+0

謝謝。我也這麼想。然而使用編譯器對我來說並不理想,因爲'T'中有哪些成員可用,取決於'T :: DOO'中設置了哪些位。我確信我正在接近這個錯誤的方式。我會找出其他的東西。但只是好奇我們可以用預處理器走多遠。 另一種選擇可能是查看是否可以使用模板元編程技巧。 – Raj 2010-05-25 13:28:54

+0

他們可能會。如果你用你想要完成的細節開啓一個新問題,我們可以看看。 – Thomas 2010-05-25 13:50:10

2

什麼會員T中可用取決於其位在T::DOO

設置這聽起來好像是T::DOO表現得像一個子類標識符。所以我認爲你的Foo和相關的類應該是保證定義DOO的類的子類。

關鍵是:爲什麼你必須使用位域?

+0

答案是有點涉及,但你完全正確。我正在使用這個API(DirectX),它允許一定的靈活性來指定如何格式化作爲輸入傳遞給其某個方法的特定結構的內容。關於如何進行結構設置的信息通過位域傳遞。在我的應用程序中,我有2個抽象 - 第一個是一個模板類,用於生成此結構的實例的集合,並且該結構本身作爲模板參數傳遞,另一個消耗此集合。 評論繼續。低於 – Raj 2010-05-25 16:07:47

+0

我想在使用該結構的特定成員的使用者類中編寫一些條件代碼,方法是檢查哪些位在位字段中設置。唷!我不知道這有多合理!由於源類的各種模板實例與結構的不同變體映射,所涉及的代碼必須進行條件編譯 - 因此試圖查看是否可以使用預處理器。 – Raj 2010-05-25 16:08:32

1

不確定這是否適用於您的情況,但可以使用模板類隔離不同的案例。例如:(使用你的代碼的修改版本從上面)

template <typename T, int N> 
struct Blah 
{ 
    void DoIt() 
    { 
     // normal DoIt() code 
    } 
}; 

template <typename T> 
struct Blah<T,5> 
{ 
    void DoIt() 
    { 
     // special DoIt() code for only when N==5 
    } 
};