2010-07-29 35 views
7

我有一個模板,我想根據參數的類型進行有條件編譯。我只關心區分「普通舊數據」(POD),即整數等或類/結構。我在Windows上使用C++ VS2008。使用Boost類型特徵的條件編譯

template<T> 
class foo 
{ 
    void bar(T do_something){ 
    #if IS_POD<T> 
     do something for simple types 
    #else 
     do something for classes/structs 
    #endif 
}} 

我一直在尋找增強庫,我可以看到他們似乎有我想要的。但是,我不明白#if聲明的正確語法是什麼。

任何幫助,將不勝感激。


編輯--- 閱讀的答覆後,我看到了我在這個問題的定義忽略了什麼。類foo是一個模板類,只需要將bar的版本實例化爲class type T即可。我正在尋找可以在編譯時解決的解決方案。希望這清除了我的問題。

回答

7

你可以不用enable_if,因爲所有你需要的是根據類型特徵派遣。 enable_if用於向/從重載解析添加/刪除模板實例。您可能希望使用呼叫特徵來選擇將對象傳遞給函數的最佳方法。通常,對象應該按引用傳遞,而POD按值傳遞。 call_traits讓我們選擇const非const參考。以下代碼使用const參考。

#include <boost/type_traits.hpp> 
#include <boost/call_traits.hpp> 

template <typename T> 
class foo { 
public: 
    void bar(typename boost::call_traits<T>::param_type obj) { 
     do_something(obj, boost::is_pod<T>()); 
    } 
private: 
    void do_something(T obj, const boost::true_type&) 
    { 
     // do something for POD 
    } 
    void do_something(const T& obj, const boost::false_type&) 
    { 
     // do something for classes 
    } 
}; 
0

這裏使用預處理器是不可能的。改爲看看Boost Enable If library

具體來說,在你的情況下,它看起來像(未測試):

void bar (typename enable_if <is_pod <T>, T>::type do_something) 
{ 
    // if is POD 
} 

void bar (typename disable_if <is_pod <T>, T>::type do_something) 
{ 
    // if not 
} 
+0

這將是一個編譯錯誤,一旦類模板實例,'T'是固定的,在這一點上,當您嘗試調用'bar'會看到兩個定義,它將無法編譯其中之一。請注意,這不是SFINAE,因爲它不會是替代失敗 - 類型在成員的實例化之前是固定的(或者我認爲,我不確定這些東西:))。 – 2010-07-29 23:28:19

3

不能與預處理解決這個問題,因爲它不知道C++。 (這是一個愚蠢的文本替換工具。)使用模板來做到這一點。

假設IsPod<T>::result回報的東西都Boolean<true>/Boolean<false>

template<T> 
class foo 
{ 
    void do_something(T obj, Boolean<true> /*is_pod*/) 
    { 
     // do something for simple types 
    } 
    void do_something(T obj, Boolean<false> /*is_pod*/) 
    { 
     // do something for classes/structs 
    } 

    void bar(T obj) 
    { 
     do_something(obj, IsPod<T>::result()); 
    } 
}