2015-10-16 2 views
4

Как я могу специализировать std::greater с помощью std::rel_ops? у меня есть что-то вроде этогоспециализируется на std :: больше через std :: rel_ops

#include <utility> 
#include <functional> 

using namespace std::rel_ops; 

struct MyStruct { 
    int field; 
    bool operator < (const MyStruct& rhs) const { 
     return field < rhs.field; 
    } 
}; 

Так что мне нужно отсортировать элементы в порядке убывания. Как я могу это сделать, используя operator <, std::rel_ops и std::greater?

ответ

4

Я предполагаю, что вы пытались сделать что-то похожее на

MyStruct ms[] = {{10}, {50}, {30}, {20}}; 
std::sort(std::begin(ms), std::end(ms), std::greater<MyStruct>{}); 

Это не удается скомпилировать, потому что нет подходящего operator> не будет найден. Это связано с тем, что std::greater полагается на ADL, чтобы найти перегрузку оператора и поиск ADL в связанных пространствах имен. std::rel_ops не является ассоциированным пространством имен для MyStruct. Вы можете заставить все работать, добавив декларацию использования в то же пространство имен, что и MyStruct, чтобы найти соответствующий operator>.

using std::rel_ops::operator>; 

Live demo

Но это некрасиво, и не является жизнеспособным решением в целом, так что забудьте о std::rel_ops и использовать Boost.Operators в Barry suggests.

+0

Почему вы считаете его уродливым? он делает именно то, что он должен делать. – Surt

+0

@Surt Это вопрос мнения, конечно, но если вы хотите других операторов равенства, то вам понадобится 4, используя объявления. С Boost.Operators вы просто извлекаете из 'boost :: total_ordered' (после определения' operator == 'также для вашего типа). – Praetorian

+0

Ну, мне нравится ваше решение, так как оно не требует участия третьей стороны. – Surt

1

Вы должны были бы сделать это таким образом:

std::vector<MyStruct> v{...}; 

std::sort(v.begin(), v.end(), [](const MyStruct& lhs, const MyStruct& rhs){ 
    using namespace std::rel_ops; 
    return lhs > rhs; 
}); 

Хотя std::rel_ops довольно неточным. Это проще в использовании boost::less_than_comparable, в котором вы просто добавить операторы непосредственно в MyStruct:

struct MyStruct 
    : boost::less_than_comparable<MyStruct> // <== adds operator>, 
              //   operator>=, 
              //  and operator<= 
{ 
    MyStruct(int i) : field(i) { } 
    int field; 

    bool operator<(const MyStruct& rhs) const { 
     return field < rhs.field; 
    } 
}; 

И тогда вы можете сортировать это очевидный способ:

std::sort(v.begin(), v.end(), std::greater<MyStruct>()); 
0

СТД :: rel_ops генерировать другие сравнения с == и < поэтому сначала необходимо определить, по крайней мере, <

bool operator<(const MyStruct & lhs, const MyStruct & rhs) { 
    return lhs.field < rhs.field; 
} 

Теперь rel_ops генерировать > так что теперь вы можете использовать std::greater в std::sort

std::sort(begin(myVector), end(myVector), std::greater<MyStruct>()); 
+0

Я уже определил оператор <, но я получил ошибку C2676 из std :: больше – AkhMa

+0

Ваш '<' имеет только один параметр, а 'std :: greater' требует два, далее ваш - член класса, который недоступен 'станд :: greater'. – Surt

+0

Я пробовал этот путь. и все еще C2676 – AkhMa

Смежные вопросы