If you have, for example, the following class declaration containing a transform constructor and a transform operator
struct A { A( int x ) : x( x ) {} operator int() const { return x; } int x; }; const A operator +( const A &a1, const A &a2 ) { return A( a1.x + a2.x ); }
that statement
a1 + a2;
where a1 and a2 are declared as, for example,
A a1( 10 ); A a2( 20 );
will be well formed because there is no need to call the transform function. Both operands correspond to declarations of the parameters of the + operator.
However, if you write, for example,
a1 + 20;
when the compiler throws an error because there is ambiguity. The compiler can either use the A( int ) conversion constructor to convert the second operand to type A , and invoke the operator defined for objects of type A Or he can use the operator int to convert the first operand to int and call the built-in operator + for objects of type int .
To avoid this ambiguity, you can declare either a constructor or an operator (or both) using the explicit function specifier.
for instance
explicit A( int x ) : x( x ) {}
or
explicit operator int() const { return x; }
In this case, there would be only one implicit transformation, and there would be no ambition.
I would like to add the above description that sometimes some conversion operators can be called implicitly, even if they are declared using the explicit function specifier.
For example, according to the C ++ standard (6.4 Selection)
- ... The value of the condition that is the expression is the value of the expression contextually converted to bool for other operators than the switch;
and (5.16 Conditional operator)
1 Group of conditional expressions from right to left. The first expression is contextually converted to bool (section 4).
So, for example, if the above class has the following conversion operator declared using the explicit function specifier
explicit operator bool() const { return x != 0; }
nevertheless, it will be called implicitly, for example, in the following statement
A a( 10 ); std::cout << ( a ? "true" : "false" ) << std::endl;
Here a will be converted to an object of type bool in the conditional statement.
EDIT: after you updated your question, this expression
w1+1;
is an exact match for the operator
wrapper operator+(int);
No conversion is required. Thus, the code compiles successfully.