Информация об изменениях

Сообщение Амбигус оператора от 21.05.2020 10:54

Изменено 21.05.2020 11:09 Marty

Амбигус оператора
Здравствуйте!

В проекте MSVC 2017 не может выбрать соответствующий оператор сравнения — говорит, что:

1>error C2593: 'operator <' is ambiguous
1>note: could be 'bool test::operator <(test::EntryType,test::EntryType)' [found using argument-dependent lookup]
1>note: or 'bool test::operator <(test::SomeInfo,test::SomeInfo)' [found using argument-dependent lookup]


Попробовал сделать минимально повторяющий проблему тест на ideone — https://ideone.com/Avb8lQ
Тест — работает, в проекте — не работает. Вроде все один к одному перенес, даже ошибку в методе int compare( const StructTest s ) перенес — там должна быть ссылка.
В чем может быть проблема?


  Если лень лезть на ideone
#include <iostream>
using namespace std;


namespace test
{

struct StructTest
{
    int i;

    int compare( const StructTest s )
    {
        if (i<s.i)      return -1;
        else if (i>s.i) return  1;
        else            return  0;
    }

}; 

bool operator<( StructTest t1, StructTest t2 )
{
    return t1.compare(t2) < 0;
}


enum class EnumTest
{
    e1, e2, e3
};

namespace utils {

inline int compare( EnumTest e1, EnumTest e2 )
{
    unsigned u1 = (unsigned)e1;
    unsigned u2 = (unsigned)e2;

    if (u1<u2)      return -1;
    else if (u1>u2) return  1;
    else            return  0;
}

} // namespace utils

inline bool operator< ( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) <  0; }
inline bool operator<=( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) <= 0; }
inline bool operator> ( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) >  0; }
inline bool operator>=( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) >= 0; }
inline bool operator==( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) == 0; }
inline bool operator!=( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) != 0; }

struct SomeOther
{
    EnumTest e;
};

} // namespace test


int main( int argc, char * argv[])
{
    test::SomeOther so1 = { test::EnumTest::e1 };
    test::SomeOther so2 = { test::EnumTest::e2 };

    if (so1.e<so2.e)
        cout<<"so1.e<so2.e\n";
    else
        cout<<"so1.e<so2.e\n";

    return 0;

}
Амбигус оператора
Здравствуйте!

В проекте MSVC 2017 не может выбрать соответствующий оператор сравнения — говорит, что:

1>error C2593: 'operator <' is ambiguous
1>note: could be 'bool test::operator <(test::EntryType,test::EntryType)' [found using argument-dependent lookup]
1>note: or 'bool test::operator <(test::SomeInfo,test::SomeInfo)' [found using argument-dependent lookup]
note: while trying to match the argument list '(test::EntryType, test::EntryType)'


Попробовал сделать минимально повторяющий проблему тест на ideone — https://ideone.com/Avb8lQ
Тест — работает, в проекте — не работает. Вроде все один к одному перенес, даже ошибку в методе int compare( const StructTest s ) перенес — там должна быть ссылка.
В чем может быть проблема?
Вроде сигнатура первого оператора в точности соответствует тому, что он ищет. Ну, по крайней мере, если судить по сообщениям

  Если лень лезть на ideone
#include <iostream>
using namespace std;


namespace test
{

struct StructTest
{
    int i;

    int compare( const StructTest s )
    {
        if (i<s.i)      return -1;
        else if (i>s.i) return  1;
        else            return  0;
    }

}; 

bool operator<( StructTest t1, StructTest t2 )
{
    return t1.compare(t2) < 0;
}


enum class EnumTest
{
    e1, e2, e3
};

namespace utils {

inline int compare( EnumTest e1, EnumTest e2 )
{
    unsigned u1 = (unsigned)e1;
    unsigned u2 = (unsigned)e2;

    if (u1<u2)      return -1;
    else if (u1>u2) return  1;
    else            return  0;
}

} // namespace utils

inline bool operator< ( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) <  0; }
inline bool operator<=( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) <= 0; }
inline bool operator> ( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) >  0; }
inline bool operator>=( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) >= 0; }
inline bool operator==( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) == 0; }
inline bool operator!=( EnumTest e1, EnumTest e2 ) { return utils::compare( e1, e2 ) != 0; }

struct SomeOther
{
    EnumTest e;
};

} // namespace test


int main( int argc, char * argv[])
{
    test::SomeOther so1 = { test::EnumTest::e1 };
    test::SomeOther so2 = { test::EnumTest::e2 };

    if (so1.e<so2.e)
        cout<<"so1.e<so2.e\n";
    else
        cout<<"so1.e<so2.e\n";

    return 0;

}