Выведенные конфликтующие типы без шаблона

Я пытаюсь создать тип, который может хранить либо int, либо double, либо uint, например:

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 { /*...*/ }
}

Когда я пытался его использовать, у меня возникали ошибки о "выведенных конфликтующих типах". Я где-то читал, что "руководство по дедукции" может помочь, но, похоже, для этого нужен шаблон. Моему типу не нужен шаблон.

Есть ли решение использовать этот тип значения без необходимости каждый раз приводить его к int, double или uint?

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

У меня такая же проблема с оператором (с разными сообщениями об ошибках)

int x=v+12;

Я думаю, мне следует добавить дополнительную перегрузку операторов, но я не нашел, какой именно.

1 ответ

Решение

// Я хочу ввести:

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

Попробуйте с

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

Проблема в подписи std::clamp() является

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

так что если вы называете это без объяснения T,

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

тип шаблона T выводится Value, от v, а также int, от 0 и из 1234.

Учитывая конфликтующие типы, вы получите ошибку.

Если вы укажете тип шаблона

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

дедукции больше нет, компилятор ожидает int в первой позиции, поэтому operator int () называется v.

Другие вопросы по тегам