2012-12-13 16 views
17

Według 20.8.5 §1, std::less jest szablon klasy z funkcji członka:Dlaczego std :: less jest szablonem klasy?

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

Czyli muszę wspomnieć rodzaj kiedy instancji szablonu, na przykład std::less<int>. Dlaczego nie jest to normalna klasa z szablonem funkcji członkowskich?

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

Wtedy może po prostu przejść std::less algorytmu bez typu argumentu, który może dostać owłosione.

Czy jest to tylko z powodów historycznych, ponieważ wczesne kompilatory (podobno) nie obsługiwały szablonów funkcji członków bardzo dobrze (a może nawet w ogóle), czy jest w tym coś głębszego?

+1

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

+7

C++ 14 będzie zawierał specjalizację, która sprawi, że 'std :: less <>()' będzie idealnie przekazywane dalej. Zobacz [N3421] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3421.htm), który (jak sądzę) został przyjęty w Portland bez modyfikacji. –

+0

@MooingDuck 'std :: less() (a," HI ")' to 'true' w moim systemie, czy to jest problem? – fredoverflow

Odpowiedz

27

To jest tak, że klasa stworzona przez instancja szablonu jest zagnieżdżona typedefs które zapewniają typu informacje o typie wynik i argumentów typów funktora:

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 dziedziczy std::binary_function, która produkuje te typedefs. Na przykład można wyodrębnić typ wyniku za pomocą std::less<T>::result_type.

W dzisiejszych czasach jest to w większości zbędne w przypadku słów kluczowych w C++ 11: decltype i auto.

+3

+1 wspaniała odpowiedź. – Mehrdad

9

Tak właśnie zrobiliśmy w C++ 98. Teraz, gdy lepiej rozumiemy szablony i przekierowujemy (z 14-letnim doświadczeniem), nowsze typy funkcji robią to, co mówisz: operator wywołania funkcji jest funkcją szablonu.

1

Propozycja Stephana, aby to zmienić, aby wszystkie takie obiekty funkcji były polimorficzne w ich operator() została przyjęta na poprzednim spotkaniu, to moje zrozumienie.

Zatem odpowiedź na pytanie "dlaczego operator wywołania funkcji nie jest szablonem?", Jest taki.

Powiązane problemy