Search code examples
c++overloadingfunction-templatesconversion-operator

Conversion operator overloading


I want to distinguish a template conversion operator between &, * and values:

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
}

If I remove constexpr operator T&() the code compiles and ui = s invokes the constexpr operator T() operator. But why?

I also get strange behaviour when I add the explicit specifier to those funcitons.

It looks like the behaviour of the conversion operator differs from normal overloading. May anyone explain this?

PS: I'm using VS2017


Solution

  • Since value is of type int, it does not make sense to create a template conversion to a template parameter reference type. If the type is not int, you have a semantic error of trying to coerce an int object to a reference of some other type.

    Redefine the reference conversion to the proper types:

    constexpr operator int&()
    {
        return value;
    }
    constexpr operator const int&() const
    {
        return value;
    }