Перегрузка оператора преобразования

Я хочу различать оператор преобразования шаблона между &, * и значениями:

struct S
{
    template <class T>
    constexpr operator T()
    {
        return value;
    }
    template <class T>
    constexpr operator T&()
    {
        return value;
    }
    template <class T>
    constexpr operator T*()
    {
        return &value;
    }
    int value;
} s{5};

int main()
{
    uint32_t ui = s; // error:  error C2440: 'initializing': cannot convert from 'S' to 'uint32_t
}

Если я удалю constexpr operator T&() код компилируется и ui = s вызывает constexpr operator T() оператор. Но почему?

Я также получаю странное поведение, когда добавляю явный спецификатор к этим функциям.

Похоже, поведение оператора преобразования отличается от обычной перегрузки. Может кто-нибудь объяснить это?

PS: я использую VS2017

1 ответ

Решение

Поскольку value имеет тип int, нет смысла создавать преобразование шаблона в ссылочный тип параметра шаблона. Если тип не int, у вас есть семантическая ошибка при попытке принуждения int возражать против ссылки какого-то другого типа.

Переопределите эталонное преобразование для соответствующих типов:

constexpr operator int&()
{
    return value;
}
constexpr operator const int&() const
{
    return value;
}
Другие вопросы по тегам