operator-overloadingc++17type-deductiondeduction-guide

Deduced conflicting types without template


I'm trying to create a type that can store either an int, a double, or an uint, like so:

struct Value
{
    /*...*/

    Value& operator=(const int value) { /*...*/ }
    Value& operator=(const double value) { /*...*/ }
    Value& operator=(const uint value) { /*...*/ }

    operator int() const { /*...*/ }
    operator double() const { /*...*/ }
    operator uint() const { /*...*/ }
}

I got errors about "deduced conflicting types" when I'm trying to use it. I read somewhere that "deduction guide" can help but it seems to require template. My type doesn't need template.

Is there a solution to use this Value type without the need to cast it in int,double or uint everytime?

Value v;
v=123;

// I would like to type:
std::clamp(v,0,1234); // error

// But I need to type:
std::clamp(int(v),0,1234); // ok

I also have the same kind of problem with operator (with different error messages)

int x=v+12;

I think I should add more operator overloading, but I don't found which one.


Solution

  • // I would like to type:

    std::clamp(v,0,1234); // error
    

    Try with

     // .......VVVVV
     std::clamp<int>(v, 0, 1234);
    

    The problem is the signature of std::clamp() is

     template<class T>
     constexpr const T& clamp( const T& v, const T& lo, const T& hi );
    

    so if you call it without explicating T,

     std::clamp(v, 0, 1234);
    

    the template type T is deduced Value, from v, and int, from 0 and from 1234.

    Given the conflicting types, you get an error.

    If you explicit the template type

     // .......VVVVV
     std::clamp<int>(v, 0, 1234);
    

    there is no more deduction, the compiler expect an int in first position so the operator int () is called over v.