std::is_default_constructible 返回嵌套类的错误值、gcc bug 或用户错误?

Rob*_*b L 5 c++ gcc gcc12

MyClass::MyData似乎是默认可构造的,但std::is_default_constructible_v<MyClass::MyData>()返回 false。这是海湾合作委员会的错误吗?godbolt 上的代码位于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;
}
Run Code Online (Sandbox Code Playgroud)

原始海报的注释:显示的副本确实回答了问题,尽管情况略有不同。

  • 第一次std::is_default_constructible检查是在声明变体时。
  • 此时,包含类尚未完全声明,也是如此std::is_default_constructible_vfalse至少在 gcc 中)。
  • 当稍后检查静态断言时,声明就完成了。该类现在可以默认构造,但不幸的是,std::is_default_constructible_v必须保持不变并且仍然是false.

我并不完全清楚这是 gcc bug(有效代码出错)还是 Microsoft bug(接受无效代码),但问题肯定是重复的。