2011-10-07 14 views
5

Mam klasy A, która ma parametr szablonu T. Istnieją przypadki użycia, gdzie klasa T oferuje funkcję func1() i są przypadki użycia, gdzie T doesn nie oferuj tego. Funkcja f() w A powinna wywoływać func1(), iff istnieje. Myślę, że powinno to być możliwe dzięki boost mpl, ale nie wiem jak. Oto niektóre pseudo kod:Zwiększ MPL: wywołanie funkcji (członek) tylko jeśli istnieje

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

Jeszcze lepiej byłoby inaczej-case:

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

Nawet jeśli uda Ci się znaleźć odpowiedni warunek, że kod się nie skompiluje. Obie gałęzie if muszą się kompilować, a jeśli funkcja nie istnieje, prawdziwa gałąź nie będzie się kompilować. –

+0

Ze specjalizacją szablonu nie jest konieczne kompilowanie obu części. W jakiś sposób musiałbym wywołać funkcję szablonu z parametrem T i ta funkcja ma zachowanie różnic, gdy T oferuje lub nie oferuje func1(). Jestem pewien, że boost mpl oferuje coś dla tego przypadku użycia. Po prostu nie wiem, jak z niego korzystać. – Heinzi

+0

Czy C++ 11 jest opcją? –

Odpowiedz

7

Boost.MPL nie radzić sobie z tym, jak jest to ściśle dla PZT i nie można nazwać członków w TMP. Boost.Fusion i Boost.TypeTraits również nic nie mają; Myślałem, że któryś z nich, ale najwyraźniej błędnie.

Here i here to niektóre rozwiązania dotyczące pisania cech wykrywających członka w C++ 03. Gdy masz taką cechę (ja to has_func1_member nazwać), można go używać do 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); 

Należy zauważyć, że z C++ 11 Łatwiej jest napisać cechę w pierwszej kolejności, chociaż to wciąż nieco tajemniczy.

+0

Czy musiałbyś napisać to sam? Czy is_member_function_pointer nie działa? http://pl.cppreference.com/w/cpp/types/is_member_function_pointer lub w Boost: 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 W C++ 03 to nie pomaga. W C++ 11 może być w stanie napisać coś, co działa, ale prawdopodobnie zawiedzie z przeciążonymi funkcjami (zgłosi fałszywy negatyw) i istnieją prostsze sposoby na to, bez tej wady. –

Powiązane problemy