比较运算符重载与转换运算符的 C++ 优先级

C++ priority of compare operator overload vs conversion operator

考虑以下程序:

#include <iostream>

using namespace std;

class Foo {
public:
    int k;

    operator int() {
        cout << "convert int" << endl;
        return k;
    }

#if USE_COMPARE
    bool operator < (int rhs) {
        cout << "compare with" << endl;
        return (k < rhs);
    }
#endif
};

int main()
{
    Foo f;
    f.k = 3;
    int m = 5;


    if (f < m) {
        cout << 1 << endl;
        return 1;
    }
    cout << 0 << endl;
    return 0;
}

定义USE_COMPARE时,if (f<m)的比较将使用比较运算符重载。如果没有定义USE_COMPARE,它会将fFoo转换为int,然后进行整数比较。在我看来,比较运算符重载的优先级高于转换运算符。任何人都可以从 C++ 标准的角度确认这一点吗?

但我认为比较运算符应该优先是自然的。但请站在C++标准的角度回答问题。

谢谢。

13.3.3.2/2

When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1)

a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined con- version sequence or an ellipsis conversion sequence, and

a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conver- sion sequence (13.3.3.1.3).

13.3.3.1/3

A well-formed implicit conversion sequence is one of the following forms: — a standard conversion sequence (13.3.3.1.1),

— a user-defined conversion sequence (13.3.3.1.2), or

— an ellipsis conversion sequence (13.3.3.1.3).

13.3.3.1/8

If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is the standard conversion sequence consisting of the identity conversion (13.3.3.1.1).

13.3.3.1.2/1

A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user- defined conversion (12.3) followed by a second standard conversion sequence. If the user-defined conversion is specified by a conversion function (12.3.2), the initial standard conversion sequence converts the source type to the implicit object parameter of the conversion function.

编译器有两种变体,如果定义了比较运算符:

1) 让

IF = Identity(f)

通话:

IF.operator <(int)

2) 让:

IF = Identity(f);
converted_int = Identity(IF.operator int());

通话:

operator < (converted_int, int);

隐式转换序列优于用户转换序列。 标准中有两个关于引号重载决议的词,如果你愿意,你可以阅读 par 13.3,或者只是 13.3.3[over.best.ics].