"在成员函数之外的封闭类的定义中需要默认成员初始值设定项" - 我的代码是不正确的?

Vit*_*meo 20 c++ language-lawyer c++11

#include <utility>

struct foo
{
    int x{0};
    foo() noexcept = default;
    void f() noexcept(noexcept(std::declval<foo&>())) {}
};

int main()
{ 
}
Run Code Online (Sandbox Code Playgroud)

关于Godbolt的实例


上面的代码编译了我测试的任何g ++版本,以及从3.6到3.9.1的clang ++,但是没有用clang ++ 4.0.0编译:

test.cpp:6:5: error: default member initializer for 'x' needed within 
definition of enclosing class 'foo' outside of member functions
    foo() noexcept = default;
    ^
type_traits:126:26: note: in instantiation of template 
class 'std::is_function<foo &>' requested here
    : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type
                        ^
type_traits:154:39: note: in instantiation of template 
class 'std::__or_<std::is_function<foo &>,
    std::is_reference<foo &>, std::is_void<foo &> >' requested here
    : public integral_constant<bool, !_Pp::value>
                                    ^
type_traits:598:14: note: in instantiation of template 
class 'std::__not_<std::__or_<std::is_function<foo &>,
    std::is_reference<foo &>, std::is_void<foo &> > >' requested here
    : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
            ^
type_traits:121:26: note: in instantiation of template 
class 'std::is_object<foo &>' requested here
    : public conditional<_B1::value, _B1, _B2>::type
                        ^
type_traits:635:14: note: in instantiation of template 
class 'std::__or_<std::is_object<foo &>,
    std::is_reference<foo &> >' requested here
    : public __or_<is_object<_Tp>, is_reference<_Tp>>::type
            ^
type_traits:1667:33: note: in instantiation of template 
class 'std::__is_referenceable<foo &>' requested here
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
                                ^
type_traits:1678:14: note: in instantiation of default 
argument for '__add_rvalue_reference_helper<foo &>'
    required here
    : public __add_rvalue_reference_helper<_Tp>
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
type_traits:2267:12: note: in instantiation of template 
class 'std::add_rvalue_reference<foo &>' requested
    here
    inline typename add_rvalue_reference<_Tp>::type
        ^
wtfff.cpp:7:32: note: while substituting explicitly-specified 
template arguments into function template 'declval'
    void f() noexcept(noexcept(std::declval<foo&>())) {}
                            ^
wtfff.cpp:5:9: note: default member initializer declared here
    int x{0};
        ^
Run Code Online (Sandbox Code Playgroud)

我的代码格式不正确吗?如果是这样,错误的含义是什么?

请注意,noexcept从构造函数或{0}初始化程序中删除x将使代码编译.

Mit*_*tch 10

从我所知道的,你的代码很好.Clang似乎很难与= default构造函数斗争,而不仅仅是手动定义默认构造函数.它的源代码中有以下spiel:

DR1351:如果非静态数据成员的brace-or-equal-initializer在可能已评估的子表达式中调用其类或默认构造函数,则该程序格式错误.

此解决方案不可行:默认构造函数的异常规范可能需要在未评估的上下文中,特别是在noexcept-expression的操作数中,并且我们无法为封闭的类计算异常规范.

在初始化程序在词法上完成之前解决默认默认构造函数的异常规范的任何尝试都将最终到达此处,我们可以在此处对其进行诊断.

我个人认为可能错误地接收了错误.但它特别提到"默认默认构造函数".

以下似乎有效:

#include <utility>

struct foo
{
    int x{0};
    foo() noexcept {} // = default;
    void f() noexcept(noexcept(std::declval<foo&>())) {}
};

int main()
{ 
}
Run Code Online (Sandbox Code Playgroud)