std::is_default_constructible returns the wrong value for a nested class, gcc bug or user error?

128 Views Asked by At

MyClass::MyData appears to be default constructible, but std::is_default_constructible_v<MyClass::MyData>() returns false. Is this a GCC bug? Code on godbolt at https://godbolt.org/z/qrfz8c7h8.

#include <variant>
#include <type_traits>

class MyClass
{
public:
    
    struct MyData
    {
        // It doesn't matter if there is a default constructor here.
        MyData() = default;

        // Fix: Instead of using "= default", if you explicitly 
        // define an empty constructor everything works. (However,
        // eliminating the constructor altogether does not fix
        // the issue.)
        //MyData() { }

        const char* m_name{ nullptr };
    };


    std::variant<MyData> m_var;

    // Using this line instead will fix the problem.
    //std::variant<MyData> m_var{ MyData{} };

    // Or, commenting out this constructor will fix the problem.
    MyClass()
    {
    }
};

// Notice the inconsistency here.  I can clearly make a default x,
// but the static assert fails.
MyClass::MyData x;
static_assert(std::is_default_constructible_v<MyClass::MyData>);

MyClass y;
static_assert(std::is_default_constructible_v<MyClass>);

int main()
{
    return 0;
}

Note from original poster: The duplicate shown does answer the question, although this is a slightly different case.

  • The first time std::is_default_constructible is checked is when the variant is declared.
  • At that time, the containing class is not fully declared, and so std::is_default_constructible_v is false (at least in gcc).
  • When the static assert is checked later, the declaration is complete. The class can now be default constructed, but unfortunately, std::is_default_constructible_v must stay the same and is still false.

It isn't completely clear to me whether this is a gcc bug (erroring on valid code) or a Microsoft bug (accepting invalid code), but the question is definitely a duplicate.

0

There are 0 best solutions below