2012-12-13 10 views
17

Nach 20.8.5 §1 ist std::less eine Klassenvorlage mit einer Elementfunktion:Warum ist std :: less eine Klassenvorlage?

template<typename T> 
struct less 
{ 
    bool operator()(const T& x, const T& y) const; 
    // ... 
}; 

Was bedeutet, ich habe die Art zu erwähnen, wenn ich die Vorlage, zum Beispiel std::less<int> instanziiert. Warum ist std::less keine normale Klasse mit einer Memberfunktionsvorlage?

struct less 
{ 
    template<typename T, typename U> 
    bool operator()(const T& x, const U& y) const; 
    // ... 
}; 

Dann konnte ich einfach std::less einem Algorithmus ohne Typ Argument übergeben, die behaarte bekommen kann.

Ist das nur aus historischen Gründen, weil frühe Compiler (angeblich) Memberfunktionsvorlagen nicht sehr gut (oder vielleicht sogar überhaupt) unterstützen, oder gibt es etwas, das tiefer liegt?

+1

'std :: string a; std :: less() (a, "HI"); '(siehe' std :: lower_bound') –

+7

C++ 14 wird eine Spezialisierung beinhalten, um 'std :: less <>()' perfekt-weiterleiten zu können. Siehe [N3421] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3421.htm), das (glaube ich) ohne Änderungen in Portland eingeführt wurde. –

+0

@MooingDuck 'std :: less() (a," HI ")' ist 'wahr 'auf meinem System, ist das ein Problem? – fredoverflow

Antwort

27

Es ist so, dass die Klasse der instanziierten Vorlage erstellt hat typedefs verschachtelt, welche Art Informationen zu dem Ergebnistyp und Argumenttypen des Funktors bieten:

template <class Arg1, class Arg2, class Result> 
    struct binary_function 
    { 
    typedef Arg1 first_argument_type; 
    typedef Arg2 second_argument_type; 
    typedef Result result_type; 
    }; 

    template <class T> 
    struct less : binary_function <T,T,bool> 
    { 
    bool operator() (const T& x, const T& y) const; 
    }; 

std::less erben von std::binary_function, die diese typedefs produziert. So können Sie beispielsweise den Ergebnistyp mit std::less<T>::result_type extrahieren.

Heutzutage ist dies meistens unnötig mit C++ 11 decltype und Schlüsselwörter.

+3

+1 große Antwort. – Mehrdad

9

So haben wir es in C++ 98 gemacht. Nun, da wir Templates und Weiterleitung besser verstehen (mit 14 Jahren Erfahrung), tun neuere Funktionstypen, was Sie sagten: Der Funktionsaufruf-Operator ist eine Template-Funktion.

1

Der Vorschlag von Stephan, dies so zu ändern, dass alle diese Funktionsobjekte in ihrer operator() polymorph sind, wurde beim vorherigen Treffen akzeptiert, ist mein Verständnis.

Also die Antwort auf Ihre Frage "Warum ist der Funktionsaufruf Operator nicht Vorlagen?", Ist, dass es ist.