Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ priority of compare operator overload vs conversion operator

Consider the following program:

#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;
}

When USE_COMPARE is defined, the comparison of if (f<m) will use the compare operator overload. If USE_COMPARE is not defined, it will convert f from Foo to int, and then do the integer compare. It seems to me that the compare operator overload is in higher priority than the conversion operator. Could any one confirm this in the C++ standard point of view?

Yet I think it's nature that the compare operator should take priority. But please answer the question in the perspective of C++ standard.

Thanks.

like image 266
Robin Hsu Avatar asked Feb 05 '15 07:02

Robin Hsu


1 Answers

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.

There are two variants for compiler, if compare operator is defined:

1) Let

IF = Identity(f)

Call:

IF.operator <(int)

2) Let:

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

Call:

operator < (converted_int, int);

Implicit-conversion sequence is better than user-conversion sequence. There are two many words in standard about overload resolution for quotes, if you want you can read par 13.3, or just 13.3.3[over.best.ics].

like image 114
ForEveR Avatar answered Sep 30 '22 01:09

ForEveR