clash of deleted template constructor and user defined conversion operator

Viewed 49

I came around a strange error with MSVC compiler.

Let's say that I have class Foo, that must not be constructed from anything but uint32_t (copy, move and default = ok).

I also have a class Bar, that defines a Foo conversion operator.

#include <cstdint>

struct Foo
{
    Foo() = default;

    constexpr Foo(const Foo&) = default;
    constexpr Foo(Foo&&) = default;

    // may be constructed only from uint32
    constexpr Foo(uint32_t word)
    {}

    // This expression is required to
    // prevent construction from types that are
    // not uint32_t or copy or move
    // See 9.5.3 Deleted definitions for an example of
    // this specific use case.
    template <typename T>
    constexpr Foo(T) = delete;

};

struct Bar
{
    constexpr operator Foo () const { return uint32_t(); }
};

int main()
{
    constexpr Foo foo = Bar();

    return 0;
}

This compiles fine with MinGW, but MSVC gives an error:

main.cpp(27): error C2280: 'Foo::Foo<Bar>(T)': attempting to reference a deleted function`

Is this behavior defined by the standard? Or is it a MSVC bug? Or maybe MinGW does something wrong?


The error can be eradicated by declaring the delete'd template constructor as explicit.

0 Answers
Related