Deduced conflicting types without template

49 views Asked by At

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.

1

There are 1 answers

0
max66 On BEST ANSWER

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