struct foo
{
struct bar {
~bar() {} // no error w/o this line
};
bar *data = nullptr; // no error w/o this line
foo() noexcept = default; // no error w/o this line
};
是的,我知道,还有一个问题exactly相同的标题,但问题有所不同(涉及noexcept
operator并且没有嵌套类型)。那里建议的解决方案(替换构造函数foo
with
foo() noexcept {}
)改变了语义,这里没有必要:这里我们有一个更好的答案(因此问题不是重复的)。
编译器:Apple LLVM version 9.0.0 (clang-900.0.37)
,完整的错误消息:
test.cc:44:5: error: default member initializer for 'data' needed within definition of enclosing class 'foo' outside of member functions
foo() noexcept = default;
^
test.cc:41:10: note: default member initializer declared here
bar* data = nullptr;
^
这是一个 clang bug。但有一个简单的解决方法。
当默认定义一个特殊成员函数时,noexcept
说明符仅用于检查编译器生成的默认特殊成员是否为noexcept
, [dcl.sft.dcl.def]:
如果显式默认的函数是用noexcept 说明符不会产生相同的结果
作为隐式声明的异常规范(18.4), then
— 如果该函数在其第一个声明中显式默认,则将其定义为已删除;
——否则,该程序格式不正确。
因此,如果删除 noexcept 说明符foo
默认构造函数,您不会更改语义,foo
仍然是不可抛出默认构造的:
#include <type_traits>
struct foo
{
struct bar {
~bar() {} // no error w/o this line
};
bar *data = nullptr; // no error w/o this line
foo()= default; // foo is noexcept, weither the declarator contains noexcept or not
};
static_assert(std::is_nothrow_default_constructible<foo>::value);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)