2016-11-02 14 views
7

Aby użyć standardowej funkcji jak std::sort na jakimś standardowym kontenerze Container<T>porównywarka że wykonuje żądaną atrybut

struct T{ 
    int x,y; 
}; 

na podstawie wartości y, trzeba napisać coś takiego (na przykład):

std::vector<T> v; 
//fill v 
std::sort(v.begin(),v.end(),[](const auto& l,const auto& r){ 
    return l.y<r.y; 
}); 

Porównywarka, która została napisana jako funkcja lambda, jest używana zbyt często i ponownie zapisywana podczas kodu dla różnych klas i atrybutów.

Biorąc pod uwagę przypadek, w którym y „s typ jest porównywalna (albo jak int lub występuje przeciążenie dla < operator), czy jest jakiś sposób, aby osiągnąć coś takiego:

std::sort(v.begin(),v.end(),imaginary::less(T::y)); // Imaginary code 

Czy jest możliwe w C++ do napisać taką funkcję, jak less? czy coś podobnego?

Pytam, ponieważ pamiętam coś takiego w jakimś zarządzanym języku (nie jestem pewien, może C# lub Java). Jednak nie jestem pewien nawet o tych informacjach, jeśli jest to prawda.

+2

Czy byłbyś zadowolony z kodem, który pozwala powiedzieć 'member_less ()'? –

+0

@Nathan: Ale to nie pozwala ci wybrać członka do sortowania według, przy wywołaniu 'std :: sort'. –

+0

@BenVoigt Ah. Nie widziałem, że właśnie to OP próbował zrobić. głupi ja. – NathanOliver

Odpowiedz

7
template<typename T, typename MT> 
struct memberwise_less 
{ 
    MT T::* const mptr; 
    auto operator()(const T& left, const T& right) const 
    { return (left.*mptr) < (right.*mptr); } 
}; 

template<typename T, typename MT> 
memberwise_less<T, MT> member_less(MT T::*mptr) 
{ 
    return { mptr }; 
} 

a następnie można zrobić

std::sort(v.begin(), v.end(), member_less(&T::y)); 
+0

To nie jest testowane na kompilacji ... jeśli udostępniasz przypadek testowy, który tworzy wektor, drukuje wyniki itp., Z chęcią dodam to do testu. –

Powiązane problemy