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