2012-11-12 153 views
5

的存在,我試圖專注一個模板,如果一個類有這樣一個特殊的成員函數(在這裏發現了另一個例子):模板檢查重載成員函數

template <typename T> 
class has_begin 
{ 
    typedef char one; 
    typedef long two; 

    template <typename C> static one test(decltype(&C::AnyFunc)) ; 
    template <typename C> static two test(...); 

public: 
    enum { value = sizeof(test<T>(0)) == sizeof(char) }; 
    enum { Yes = sizeof(has_begin<T>::test<T>(0)) == 1 }; 
    enum { No = !Yes }; 
}; 

這種運作良好,直到AnyFunc超載:

class B : public vector<int> 
{ 
public: 
    void AnyFunc() const; 
    void AnyFunc(); 
}; 

如何重寫我的測試代碼以從我的模板中獲得「是」?

+0

好問題。一個非常微不足道的問題,可以由於SFINAE而無聲無息地發現。 – iammilind

回答

1

發現其作品的版本:如果您想驗證對象const函數,使用此

template <typename C> static one test(decltype(((C*)0)->AnyFunc())*) ; 

template <typename C> static one test(decltype(((const C*)0)->AnyFunc())*) ; 

該版本將無法檢測與參數功能:

class B : public std::vector<int> 
{ 
public: 
    //void AnyFunc() const; 
    //void AnyFunc(); 
    int AnyFunc(int); 
}; 
+1

@Klaus這就是爲什麼我在'decltype()'之後加了'*'......我在發佈之前檢查它是否工作:http://ideone.com/8Tli7t – PiotrNycz

+0

在閱讀第二個答案後,我得到了解決方案在我的環境中。非常感謝! – Klaus

+0

是的,我忘記了decltype之後的*!對不起,我的錯!從第二個答案中查看std :: add_pointer的後面我得到了這個工作。 – Klaus

2

不帶參數的重載函數名稱(13.4p1)的使用必須解析爲唱歌le過載(13.4p4),否則會發生替換失敗。

如果您正在測試的一個成員函數的存在,那麼你應該知道,你打算與調用它的參數:

template <typename C> static one test(
     typename std::add_pointer<decltype(std::declval<C>().AnyFunc())>::type); 

在一般情況下,你可以使用可變參數模板和類似result_of模式:

template <typename C, typename... Args> static one test(
     typename std::add_pointer<decltype(
      std::declval<C>(std::declval<Args>()...).AnyFunc())>::type); 

使用add_pointer允許這與不是允許作爲函數參數類型函數的返回類型的工作(如void)。