“成员函数外部的封闭类的定义中需要使用默认成员初始化程序"-我的代码格式错误吗? [英] “Default member initializer needed within definition of enclosing class outside of member functions” - is my code ill-formed?

查看:146
本文介绍了“成员函数外部的封闭类的定义中需要使用默认成员初始化程序"-我的代码格式错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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
};

是的,我知道,还有一个问题,标题完全相同,但标题有所不同(涉及到noexcept operator 并且没有嵌套类型).建议的解决方案(用

替换foo的构造函数

Yes, I know, there is another question with exactly the same title, but a somewhat different problem (involving a noexcept operator and no nested type). The solution suggested there (replacing the constructor of foo with

    foo() noexcept {}

)改变了语义,在这里没有必要:这里我们有一个更好的答案(因此问题不是重复的).

) changes the semantics and it not necessary here: here we have a better answer (hence the question is not a duplicate).

编译器:Apple LLVM version 9.0.0 (clang-900.0.37),完整的错误消息:

compiler: Apple LLVM version 9.0.0 (clang-900.0.37), full error message:

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;
         ^

推荐答案

这是一个叮叮当当的错误.但是有一个简单的解决方法.

This is a clang bug. But there is a simple workaround.

当将默认的特殊成员函数定义为默认成员函数时,noexcept说明符仅用于检查编译器生成的默认特殊成员将为noexcept

When one defines a special member function as defaulted, the noexcept specifier is just used to check that the defaulted special member generated by the compiler will be noexcept, [dcl.sft.dcl.def]:

如果显式默认的函数声明为 noexcept-specifier 那不会产生相同的 异常说明作为隐式声明(18.4),然后

If a function that is explicitly defaulted is declared with a noexcept-specifier that does not produce the same exception specification as the implicit declaration (18.4), then

-如果该函数在其第一个声明中被明确默认为默认值,则将其定义为已删除;

— if the function is explicitly defaulted on its first declaration, it is defined as deleted;

-否则,程序格式错误.

— otherwise, the program is ill-formed.

因此,如果删除foo默认构造函数的noexcept分隔符,则不会更改语义,foo仍将不具有默认可构造变量:

So if you remove the noexcept sepcifier of foo default constructor, you will not change the semantic, foo will still be nothrow default constructible:

#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);

这篇关于“成员函数外部的封闭类的定义中需要使用默认成员初始化程序"-我的代码格式错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆