Why conversion doesn't work with custom operators in C ++?

Consider the following code:

class C { public: int operator-(int x) { return 3-x; } }; class wrapper { public: operator C() { static C z; return z; } } wrap; int main() { return wrap-3; } 

it gives this error in g ++:

 test.cpp: In function 'int main()': test.cpp:17:17: error: no match for 'operator-' in 'wrap - 3' 

The conversion operator seems to work because this version works:

 class wrapper { public: operator int() { static int z=3; return z--; } } wrap; int main() { return wrap-3; } 

operator- also works because this code compiles:

 class C { public: int operator-(int x) { return 3-x; } }; int main() { C c return c-3; } 

What is wrong with the combination of the two? Why can't an operator be applied after an implicit conversion? Are there any workarounds to solve this problem?

+4
source share
3 answers

Implicit conversions are not performed on the first operand when matching a member function. Just make your operator a non-member, perhaps a friend:

 class C { }; int operator-(C c, int x) { return 3-x; } 

From [over.match.oper]:

- If T1 is a complete class type, the set of candidate candidates is the result of a qualified search T1:: operator@ (13.3.1.1.1); otherwise, the set of candidate candidates is empty.

+5
source

It does not compile (using GCC) because it will not be able to bind two custom conversions to get from wrapper to int : first to C , then to int . The standard does not allow this. See David Rodriguez's answer in another thread .

+1
source

When you return wrap-3; the compiler does not know to convert the shell to C, so that for the calculation it searches for an operator shell or conversion to a shell in a numeric type. Just because C has an operator - doesn't the compiler implicitly convert to it, you can have several conversion operators in the shell, which compiler should convert to?

Either explicitly tell the compiler to convert to C to add a wrapper statement like this.

 class wrapper { public: operator C() { static C z; return z; } int operator-(int x) { return C()-x; } } wrap; 
0
source

Source: https://habr.com/ru/post/1393609/


All Articles