简体   繁体   中英

Implicit conversion to type with user defined operation

I would like to use the user defined operator for type which is inside a class:

class TWithUserDefinedOp
{
private: int a{42};
public: operator *(const TWithUserDefinedOp& other) { return a * other.a;}
};

class Wrap 
{
private: TWithUserDefinedOp a;
public: operator TWithUserDefinedOp() const { return a; }
}

Now when I would like to multiple the Wrap classes, I'd expect it to work

Wrap a, b;
auto mul = a * b; //Error: Wrap does not define this operator or a conversion to a type acceptable to the predefined operator

Now if I change the wrap to hold the integral type:

 class WrapIntegral 
 {
 private: int a{42};
 public: operator int() const { return a; }
 }

The multiplication now works.

WrapIntergal a,b;
auto mulInt = a * b; // this works ok

I have read in other similiar questions that C++ only allows 1 level of implicit conversion. If I count correctly, there is just one implicit conversion in the first example. From Wrap to TWithUserDefinedOp for which the operator * is defined. What is my misunderstanding or what do I do wrong here?

I think the issue is that you need a conversion from your class type to an Integral type, which is the predefined one for Multiplication operator. In your first example you don-t have it.

the op* has the signature: TWithUserDefinedOp operator* (const TWithUserDefinedOp& other). same for Wrap class.

this means that the first conversion is (Wrap -> TWithUserDefinedOp) and the second one expects (TWithUserDefinedOp -> Wrap).

a possible fix for your original code:

#include <iostream>
#include <typeinfo>

using namespace std;

class TWithUserDefinedOp
{
private:
    int a{ 42 };
public:
    TWithUserDefinedOp(int a_ = 1) : a(a_) {}
    friend TWithUserDefinedOp operator* (const TWithUserDefinedOp& a, const TWithUserDefinedOp& b);
};

TWithUserDefinedOp operator* (const TWithUserDefinedOp& a, const TWithUserDefinedOp& b)
{
    return TWithUserDefinedOp(a.a * b.a);
}

class Wrap
{
private:
    TWithUserDefinedOp a;
public:
    Wrap(const TWithUserDefinedOp& a_ = TWithUserDefinedOp()) : a(a_) {}
    operator TWithUserDefinedOp() const
    {
        return a;
    }
};

int main()
{
    Wrap a, b;    
    auto c = a * b;
    cout << typeid(c).name() << "\n";   // TWithUserDefinedOp
    Wrap d = a * b;
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM