2014-05-15 69 views
0

我一直在尋找如何調用一個函數的答案,只有當它存在並發現此問題的一些代碼Is it possible to write a template to check for a function's existence?。我試圖使用std :: is_member_function_pointer作爲鑑別器來調用專門的模板代碼。但是我在輸出中看到了兩次,當我期望看到錯誤而且是真實的時候。有關這可能是爲什麼的任何建議?該代碼還可以在https://ideone.com/HZ17Wf看出std :: is_member_function_pointer始終返回true

#include <iostream> 
#include <utility> 
#include <type_traits> 

namespace Ckb 
{ 

struct Version 
{ 
    enum { Major = 1, Minor = 0, Release = 0 }; 
    void CheckDependencies() 
    { 
     std::cout << "Ckb Check" << std::endl; 
    } 
}; 

} // namespace Ckb 

namespace Cg 
{ 

struct Version { enum { Major = 1, Minor = 8, Release = 1 }; }; 

} // namespace Cg 

template <typename T, bool> struct RunCheck 
{ void operator()() {std::cout << "false" << std::endl;} }; 

template <typename T> struct RunCheck<T, true> 
{ void operator()() { std::cout << "true" << std::endl; } }; 

template <typename T> void Do() 
{ 
    RunCheck<T, std::is_member_function_pointer<void(T::*)()>::value>()(); 
} 

int main() 
{ 
    Do<Cg::Version>(); 
    Do<Ckb::Version>(); 
    return 0; 
} 
+0

你想檢查是否'CheckDependencies()'存在(用正確的簽名)? – Jarod42

回答

4

void(T::*)()member_function_pointer(即使T沒有任何匹配方法)。

我想你想使用類似:

#include <cstdint> 

#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)    \ 
    template <typename U>             \ 
    class traitsName              \ 
    {                  \ 
    private:                \ 
     template<typename T, T> struct helper;        \ 
     template<typename T>            \ 
     static std::uint8_t check(helper<signature, &funcName>*);   \ 
     template<typename T> static std::uint16_t check(...);    \ 
    public:                 \ 
     static                \ 
     constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \ 
    } 

DEFINE_HAS_SIGNATURE(has_CheckDependencies, T::CheckDependencies, void (T::*)()); 

,然後使用它:

template <typename T> void Do() 
{ 
    RunCheck<T, has_CheckDependencies<T>::value>()(); 
} 
+0

非常感謝您的幫助,@ Jarod42。這適用於C++ 11編譯器。我已經嘗試過其他類型,並簡單地改變類型,並且int也可以工作。可悲的是,我使用的目標編譯器來自舊的Borland家族(現在是Embarcadero),而版本4不能編譯。我認爲DEFINE_HAS_SIGNATURE(has_CheckDependencies,T :: CheckDependencies,void(T :: *)())行有問題,因爲有些奇怪的原因需要知道T是什麼。心理......無論如何,再次感謝您的幫助。 – DSV