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
isfalse
(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 stillfalse
.
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.