2010-07-29 21 views
7

Mam szablon, który chciałbym warunkowo skompilować w zależności od typu argumentu. Dbam tylko o różnicowanie "zwykłych starych danych" (POD), tj. Liczb całkowitych, itp. Lub klas/struktur. Używam C++ VS2008 w systemie Windows.Kompilacja warunkowa przy użyciu cech typu Boost

template<T> 
class foo 
{ 
    void bar(T do_something){ 
    #if IS_POD<T> 
     do something for simple types 
    #else 
     do something for classes/structs 
    #endif 
}} 

Oglądałem bibliotekę doładowania i widzę, że wydają się mieć to, czego chcę. Jednak nie rozumiem, jaka byłaby poprawna składnia instrukcji #if.

Każda pomoc zostanie doceniona.


Edit --- Po przeczytaniu odpowiedzi, widzę coś przeoczyłem w mojej definicji pytanie. Klasa foo jest klasą szablonową, która wymaga tylko wersji bar, która jest poprawna dla class type T. Szukałem rozwiązania, które można rozwiązać w czasie kompilacji. Mam nadzieję, że to rozwiąże mój problem.

Odpowiedz

7

można to zrobić bez enable_if, ponieważ wszystko, co potrzebne jest do wysyłki w zależności od cech typu. enable_if służy do dodawania/usuwania instancji szablonów z/do rozdzielczości przeciążania. Możesz użyć funkcji połączenia, aby wybrać najlepszą metodę przekazywania obiektów do swojej funkcji. Zasadniczo obiekty powinny być przekazywane przez odniesienie, podczas gdy POD jest przekazywane przez wartość. call_traits wybierzmy między const i non-const referencje. Poniższy kod wykorzystuje odniesienie const.

#include <boost/type_traits.hpp> 
#include <boost/call_traits.hpp> 

template <typename T> 
class foo { 
public: 
    void bar(typename boost::call_traits<T>::param_type obj) { 
     do_something(obj, boost::is_pod<T>()); 
    } 
private: 
    void do_something(T obj, const boost::true_type&) 
    { 
     // do something for POD 
    } 
    void do_something(const T& obj, const boost::false_type&) 
    { 
     // do something for classes 
    } 
}; 
0

Używanie preprocesora tutaj nie jest możliwe. Spójrz na numer Boost Enable If library.

Konkretnie, w twoim przypadku to będzie wyglądać (nie testowane):

void bar (typename enable_if <is_pod <T>, T>::type do_something) 
{ 
    // if is POD 
} 

void bar (typename disable_if <is_pod <T>, T>::type do_something) 
{ 
    // if not 
} 
+0

Będzie to błąd kompilacji, gdy szablon jest instancja klasy, 'T' jest stała, i w tym momencie, gdy spróbujesz zadzwonić' bar' będzie zobaczyć dwie definicje i nie będzie można skompilować jeden z nich. Zauważ, że to nie jest SFINAE, ponieważ nie będzie to niepowodzenie zastępowania - typ jest naprawiony przed utworzeniem elementu (tak myślę, nigdy nie jestem pewien z tymi rzeczami :)). –

3

Nie można rozwiązać ten problem z preprocesora, ponieważ nie wie o C++. (Jest to nieme narzędzie zastępujące tekst). Użyj szablonów, aby to zrobić.

Zakładając IsPod<T>::result powraca coś alike Boolean<true>/Boolean<false>:

template<T> 
class foo 
{ 
    void do_something(T obj, Boolean<true> /*is_pod*/) 
    { 
     // do something for simple types 
    } 
    void do_something(T obj, Boolean<false> /*is_pod*/) 
    { 
     // do something for classes/structs 
    } 

    void bar(T obj) 
    { 
     do_something(obj, IsPod<T>::result()); 
    } 
} 
Powiązane problemy