2011-10-07 32 views
5

我有了一個模板參數T有使用案例,其中T類提供了一個功能func1的(A類A(成員)函數),而且用例,其中T沒有按不提供它。 A中的函數f()應該調用func1(),如果它存在。我認爲這應該可以用boost mpl,但我不知道如何。 這裏是一些僞代碼:升壓MPL:只呼叫如果存在

template<class T> 
class A 
{ 
    void f(T param) 
    { 
     if(T::func1 is an existing function) 
      param.func1(); 
    } 
}; 

更妙的是別的情況:

template<class T> 
class A 
{ 
    void f(T param) 
    { 
     if(T::func1 is an existing function) 
      param.func1(); 
     else 
      cout << "func1 doesn't exist" << endl; 
    } 
}; 
+2

即使你設法找到一個合適的條件,即代碼將不會編譯。 if的兩個分支都必須進行編譯,如果函數不存在,則真正的分支將不會編譯。 –

+0

使用模板專業化,兩部分都不需要編譯。不知何故,我將不得不使用參數T調用模板函數,並且當T提供或不提供func1()時,此函數具有不同的行爲。我確信boost mpl爲這個用例提供了一些東西。我只是不知道如何使用它。 – Heinzi

+0

C++ 11是一個選項嗎? –

回答

7

Boost.MPL不與處理,因爲它是嚴格的TMP,你不能調用成員在TMP中。 Boost.Fusion和Boost.TypeTraits也沒有任何東西;我以爲其中一個會,但顯然我誤解了。

Herehere是如何編寫特徵以檢測C++ 03中的成員的一些解決方案。一旦你有這樣的特質(我稱之爲has_func1_member),你可以用它來SFINAE:

template<typename T> 
typename boost::enable_if<has_func1_member<T> >::type 
maybe_call(T& t) 
{ t.func1(); } 

template<typename T> 
typename boost::disable_if<has_func1_member<T> >::type 
maybe_call(T&) 
{ 
    // handle missing member case 
} 

// your example code would then do: 
maybe_call(param); 

注意與C++ 11它更容易寫在首位的特質,但它仍然是有點神祕。

+0

你真的需要自己寫嗎? is_member_function_pointer不是訣竅嗎? http://en.cppreference.com/w/cpp/types/is_member_function_pointer或升壓:http://www.boost.org/doc/libs/1_51_0/libs/type_traits/doc/html/boost_typetraits/reference/is_member_function_pointer .html – Gurgeh

+0

@Gurgeh在C++ 03中它沒有幫助。在C++ 11中,你可能能夠編寫一些可行的方法,但它可能會因爲重載的成員函數而失敗(會報告一個錯誤的否定結果),並且有更簡單的方法可以做到這一點。 –