2010-09-23 24 views
7

__if_exists jest Microsoft określonego słowa kluczowego do testowania istnienia identyfikatorów w czasie kompilacji:Czy istnieje odpowiednik __if_exists w gnu C++?

msdn:__if_exists

To może przyjść bardzo przydatna przy „podrobić” specjalizację szablonu co w niektórych przypadkach daje naprawdę dużo bardziej proste, czytelny i skuteczniejszy niż inne metody, takie jak "prawdziwa" specjalizacja, przeciążanie czy cokolwiek innego.

Ale teraz muszę portu dużego projektu GNU C++ i myślę, że zacznę się trochę płakać jeśli będę musiał znaleźć inne sposoby dla (co prawda nielicznych) przypadkach użyłem go

+0

Mówisz o #ifdef? http://stackoverflow.com/questions/1802107/define-ifdef-undef-endif – karlphillip

+3

To trochę niepokojące widzieć "' __if_exists' "i" szablon "w tym samym miejscu. W każdym razie, jeśli jest tylko kilka miejsc, w których jest on używany, prawdopodobnie lepiej przerobić tylko te fragmenty kodu. –

+0

Nie, nie jest to to samo, co #ifdef, podobnie jak w przypadku #efdef można testować tylko prekompilator nie definiuje np. członkowie klasy –

Odpowiedz

4

to Zdeprymowanie słowa kluczowego w mojej opinii ...

Niestety, nie istnieje w gcc, o ile wiem, ale może po prostu nie wiem o tym.

Właściwym sposobem C++ jest poradzenie sobie z tym poprzez użycie Koncepcji, tj. Dostosowanie operacji przenoszonych na typ w zależności od pewnych wymagań.

Zwykle jest to wykonywane z traits zamiast rzeczywistych pojęć, ponieważ łatwiej jest umieścić w miejscu:

template <typename T> 
struct has_dump: boost::mpl::false_ {}; 

A potem zrzucić włączyć swoje typy przez specjalizującą strukturę has_dump.

Najprostszym jest zdefiniowanie 3 metody, jedną do trasy, dwa pozostałe do wykonania różne oddziały:

template <typename T> 
void dump(T& t, boost::mpl::true_ const& dummy) 
{ 
    t.Dump(); 
} 

template <typename T> 
void dump(T& t, boost::mpl::false_ const& dummy) 
{ 
    std::cout << typeid(T).name() << " does not have Dump\n"; 
} 

template <typename T> 
void dump(T& t) { dump(t, has_dump<T>()); } 

Innym zastosowaniem cech typu byłaby w połączeniu z enable_if obiektów:

template <typename T> 
typename boost::enable_if< has_dump<T> >::type dump(T& t) 
{ 
    t.Dump(); 
} 

// disable_if exists too... 

Tutaj, zamiast komunikatu o błędzie środowiska wykonawczego, można uzyskać błąd podczas kompilacji, jeśli typ nie ma włączonej has_dump, nie wiem, czy tego chcesz.

Jednak obie te metody są dość uciążliwe, ponieważ wykrywanie nie jest automatyczne. Dlatego istnieje biblioteka Boost.Concept.

Pomysł polega na tym, że kontrola zostanie przeprowadzona przez obiekt Concept, stworzony w celu przetestowania wymagań, dzięki czemu nie trzeba już dłużej wyspecjalizować cech, które ułatwiają rozwój. Jednak zawsze uważałem, że dokumentacja Boost.Concept jest nieco brakuje.

+1

Cóż, twoja alternatywa jest zbyt skomplikowana dla mojego celu, ale zaakceptuję twoją odpowiedź jako "nie", jeśli w ciągu kilku dni nikt nie wymyśli prawdziwego prostego "tak". –

+0

@kaptnole: Zgadzam się, to gadatliwe, całe pojęcia były po prostu tym ... miejmy nadzieję, że zrobią to w C++ 1x –

+0

Czy mógłbyś podać więcej informacji na temat następującej instrukcji: "A potem włączasz dump twoich typów przez wyspecjalizowanie struktury has_dump? "Myślę, że odnosisz się do czegoś w stylu" szablon <> struct has_dump : boost :: mpl :: true_ {}; "jak omówiono w artykule znalezionym pod adresem http: // en .cppreference.com/w/cpp/language/template_specialization ale nie jestem pewien –

Powiązane problemy