members comparison
От: regnar  
Дата: 11.04.15 20:26
Оценка:
Очень сильно надоело писать такую лапшу:

bool operator==(...)
{
    return lhs.a == rhs.a && lhs.b == rhs.b && ...
}


Хочется как-то так

bool operator==(...)
{
    if(membersEqual(lhs, rhs, <список полей исключений>)){ как-то по-своему сравниваем }
    return false;
}


Есть варианты?
Re: members comparison
От: Evgeny.Panasyuk Россия  
Дата: 11.04.15 21:14
Оценка: 2 (1) +1
Здравствуйте, regnar, Вы писали:

R>Есть варианты?


Boost.Fusion, но требуется первоначальное перечисление полей в макросе (например BOOST_FUSION_DEFINE_STRUCT или BOOST_FUSION_ADAPT_STRUCT). Зато можно получить и operator==, и operator<, и hash_value, и serialize, да и вообще произвольный обход полей структуры.

P.S. А так — ждём появление compile-time reflection в стандарте.
Re: members comparison
От: Maxim Yurchuk  
Дата: 12.04.15 11:51
Оценка: 2 (1)
Здравствуйте, regnar, Вы писали:

R>Хочется как-то так


R>
R>bool operator==(...)
R>{
R>    if(membersEqual(lhs, rhs, <список полей исключений>)){ как-то по-своему сравниваем }
R>    return false;
R>}
R>


R>Есть варианты?


Может этот способ подойдет:


template <typename T>
bool IsMembersEqual(const T& lhs, const T& rhs)
{
    return true;
}

template <typename T, typename FirstMemberPtr, typename ... OtherMembersPtrs>
bool IsMembersEqual(const T& lhs, const T& rhs, FirstMemberPtr T::*ptr, OtherMembersPtrs ... otherPtrs)
{
    return (lhs.*ptr == rhs.*ptr) && IsMembersEqual(lhs, rhs, otherPtrs ...);
}


struct Sample
{
    // ...
    
    friend bool operator==(const Sample& lhs, const Sample& rhs)
    {
        // compare only m_a and m_b
        return IsMembersEqual(lhs, rhs, &Sample::m_a, &Sample::m_b);
    }

private:
    int m_a;
    short m_b;
    long m_c;
};

?
Re: members comparison
От: uzhas Ниоткуда  
Дата: 12.04.15 19:52
Оценка: 12 (2)
Здравствуйте, regnar, Вы писали:

R>Есть варианты?


очень удобным в некоторых случаях является функция std::tie
пример (компиляцию не проверял)
struct S
{
  int A = 0;
  std::string B;
  double C = 0.0;
};

bool operator==(const S& lhs, const S& rhs)
{
  return std::tie(lhs.A, lhs.B, lhs.C) == std::tie(rhs.A, rhs.B, rhs.C);
}

bool operator<(const S& lhs, const S& rhs)
{
  return std::tie(lhs.A, lhs.B, lhs.C) < std::tie(rhs.A, rhs.B, rhs.C);
}
Re[2]: members comparison
От: Кодт Россия  
Дата: 12.04.15 20:48
Оценка: 24 (6) +2
Здравствуйте, uzhas, Вы писали:

U>очень удобным в некоторых случаях является функция std::tie


Ещё удобнее было бы избавиться от копипасто-опасного кода — сделать что-то такое
struct S { A a; B b; C c; };
auto const S_fields = [](S const& obj) -> auto { return std::tie(obj.a, obj.b, obj.c); };

bool operator == (S const& lhs, S const& rhs) { return S_fields(lhs) == S_fields(rhs); }
bool operator <  (S const& lhs, S const& rhs) { return S_fields(lhs) <  S_fields(rhs); }


Компилируется http://ideone.com/wV2FJ6
Перекуём баги на фичи!
Отредактировано 12.04.2015 20:50 Кодт . Предыдущая версия .
Re: members comparison
От: vpchelko  
Дата: 14.04.15 19:19
Оценка: :)
Здравствуйте, regnar, Вы писали:

R>Очень сильно надоело писать такую лапшу:


R>
R>bool operator==(...)
R>{
R>    return lhs.a == rhs.a && lhs.b == rhs.b && ...
R>}
R>


R>Хочется как-то так


R>
R>bool operator==(...)
R>{
R>    if(membersEqual(lhs, rhs, <список полей исключений>)){ как-то по-своему сравниваем }
R>    return false;
R>}
R>


R>Есть варианты?


ХЗ в нормальных IDE (правда для Java), есть автогенерация компараторов. Но даже эту фичу я очень редко использую
Сало Украине, Героям Сала
Отредактировано 14.04.2015 19:20 vpchelko . Предыдущая версия .
Re[2]: members comparison
От: uzhas Ниоткуда  
Дата: 15.04.15 08:29
Оценка:
Здравствуйте, vpchelko, Вы писали:

V>правда для Java


java — это не тут
Re[3]: members comparison
От: vpchelko  
Дата: 15.04.15 18:28
Оценка:
Здравствуйте, uzhas, Вы писали:

U>java — это не тут


Невелика разница — с сабжем должна справляться IDE.
Сало Украине, Героям Сала
Re: members comparison
От: Co2009  
Дата: 25.04.15 21:09
Оценка:
Здравствуйте, regnar, Вы писали:

R>Очень сильно надоело писать такую лапшу:


R>
R>bool operator==(...)
R>{
R>    return lhs.a == rhs.a && lhs.b == rhs.b && ...
R>}
R>


R>Хочется как-то так


R>
R>bool operator==(...)
R>{
R>    if(membersEqual(lhs, rhs, <список полей исключений>)){ как-то по-своему сравниваем }
R>    return false;
R>}
R>


R>Есть варианты?


Написал макросы. Hапример
#define EQUAL_STRUCT_3( a, b, c) template<typename T> bool operator == ( T const &Rhs) const { return a == Rhs.a && b == Rhs.b && c == Rhs.c; }

Раньше подобный макрос использовал для сериализации.
Re: members comparison
От: Cruser Украина  
Дата: 29.04.15 14:49
Оценка:
R>Есть варианты?

Сделать структуры упакованными и сравнимать через memcmp()
Re[2]: members comparison
От: Mr.Delphist  
Дата: 05.05.15 17:43
Оценка:
Здравствуйте, Cruser, Вы писали:

R>>Есть варианты?


C> Сделать структуры упакованными и сравнимать через memcmp()


Но при этом, как я понимаю, мы пролетаем мимо non-POD types, переопределённых операторов и т.п.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.