2011-10-07 49 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中,你可能能够编写一些可行的方法,但它可能会因为重载的成员函数而失败(会报告一个错误的否定结果),并且有更简单的方法可以做到这一点。 –