implicit conversions from and to class types

后端 未结 2 1363
说谎
说谎 2020-12-28 22:20

I am studying converting constructors and conversion operators in C++. What I\'ve learned so far is that any non-explicit constructor that takes only one parameter (and any

2条回答
  •  长情又很酷
    2020-12-28 23:07

    If you have for example the following class declaration that contains a conversion constructor and a conversion 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 );
    }
    

    then statement

    a1 + a2;
    

    where a1 and a2 are declared like for example

    A a1( 10 );
    A a2( 20 );
    

    will be well-formed because there is no need to call a conversion function. The both operands match the parameter declarations of the operator +.

    However if you will write for example

    a1 + 20;
    

    when the compiler issues an error because there is an ambiguity. The compiler can either apply conversion constructor A( int ) to convert the second operand to type A and call the operator defined for objects of type A. Or it can apply the conversion operator operator int to convert the first operand to type int and call the built-in operator + for objects of type int.

    To avoid this ambiguity you could declare either the constructor or the operator (or the both) with function specifier explicit.

    For example

        explicit A( int x ) : x( x ) {}
    

    or

        explicit operator int() const { return x; }
    

    In this case only one implicit conversion would exist and there was not an ambigiuty.

    I would like to append the above description that sometimes some converion operators can be called implicitly even if they are declared with the function specifier explicit.

    For example According to the C++ Standard (6.4 Selection statements)

    1. ...The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch;

    and (5.16 Conditional operator)

    1 Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4).

    So for example if the above class has the following conversion operator declared with the function specifier explicit

    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 operator.

    EDIT: After you updated your question this expression

    w1+1; 
    

    is an exact match for operator

    wrapper operator+(int);
    

    Neither conversion are required. So the code compiles successfully.

提交回复
热议问题