2016-04-08 10 views
2

Gibt es consExpr oder andere Kompilierzeitäquivalente zu den STL-Funktions- und anderen Bibliotheken für die Verwendung mit Metaprogrammierung? Genauer gesagt, versuche ich einige Metaprogramme zu schreiben, die SFINAE verwenden, um bestimmte Bedingungen zu bewerten und die entsprechenden Typen zu generieren. Beispiel:C++ STL-funktionale Entsprechungen für Metaprogrammierung

template<int A, int B> 
enable_if_t<(A < B)> my_func() {// do something 
} 

template<int A, int B> 
enable_if_t<!(A < B)> my_func() {// do nothing 
} 

Idealerweise würde ich der Benutzer gerne in der Lage sein, in einem Komparator passieren (wie std::less<int>), eher als schwer zu < Codierung. So etwas wie:

template<int A, int B, class comp = std::less<int>> 
enable_if_t<comp(A, B)> my_func() {// do something 
} 

template<int A, int B, class comp = std::less<int>> 
enable_if_t<comp(A, B)> my_func() {// do nothing 
} 

Da jedoch die funktionalen Objekte sind nicht konstante Ausdrücke, werden sie nicht bei der Kompilierung ausgewertet zu werden und so funktioniert das nicht. Was wäre der richtige Weg, um so etwas zu implementieren?

+3

'enable_if_t '? – cpplearner

+0

Das funktioniert nicht. Der Compiler beschwert sich: Nicht-Typ Vorlage Argument ist kein konstanter Ausdruck –

+0

'enable_if_t' ist nur in [C++ 14] definiert (http://en.cppreference.com/w/cpp/types/enable_if). Wie erwarten Sie, dass es mit C++ 11 funktioniert? Hast du es selbst definiert? –

Antwort

6

std::less<int>(int, int) ist kein Konstruktor für std::less. Der einzige Konstruktor für std::less ist () (ich bevorzuge {}, weil es klar macht, dass ich etwas konstruiere).

Seit 14 C++ ein constexpr hat operator(), dass (wenn < auf den beteiligten Arten ist constexpr) kann bei der Kompilierung ausgewertet werden.

So:

template<int A, int B, class comp = std::less<int>> 
enable_if_t<comp{}(A, B)> my_func() {// do something 
} 

template<int A, int B, class comp = std::less<int>> 
enable_if_t<!comp{}(A, B)> my_func() {// do nothing 
} 

funktionieren sollte.

in C++ 11

namespace notstd { 
    template<class T=void> 
    struct less { 
    constexpr bool operator()(T const& lhs, T const& rhs)const{ 
     return lhs<rhs; 
    } 
    }; 
    template<> 
    struct less<void> { 
    template<class T, class U> 
    constexpr bool operator()(T const& lhs, U const& rhs)const{ 
     return lhs<rhs; 
    } 
    // maybe also add this: 
    //struct is_transparent {}; 
    } 
} 

(Ihre < auf Ihrem System unter der Annahme ein Gesamtauftrag auf Zeiger ist) funktionieren soll (std::less<T> mit notstd::less<T> ersetzen).

+0

Sorry, habe gerade die ursprüngliche Frage aktualisiert, ich muss immer noch auf C++ 11 sein. –

+0

Und wenn Sie bei C++ 11 stecken bleiben, können Sie noch eigene 'conetexpr' Vergleichsfunktionen/Funktoren/was auch immer definieren ... :-) – jotik

+0

letzteres sollte negiert werden,'! Comp {} (A, B) ' –

Verwandte Themen