2017-10-21 104 views
7
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操作并没有嵌套的类型)。该解决方案建议有(与“在成员函数外部封装类的定义中需要的默认成员初始值设定项” - 是我的代码格式不正确吗?

foo() noexcept {} 

更换的foo构造函数)改变语义,它没有必要在这里:我们这里有一个更好的答案(因此这个问题不是一个重复)。

编译: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; 
     ^
+1

你可以只declarare析构函数在'bar'和将其定义在课堂外。这种方式编译。 – skypjack

+0

这是一个铿锵虫。 – Oliv

+0

[“在成员函数外部封装类的定义中需要的默认成员初始值设定项”的可能重复项是否是我的代码格式不正确?](https://stackoverflow.com/questions/43819314/default-member-initializer-needed- within-definition-of-enclosing-class-outside) –

回答

1

的问题可以通过违约嵌套类

struct foo 
{ 
    struct bar { 
     ~bar() = default;  // this fixes it 
    }; 
    bar *data = nullptr;   // no error w/o this line 
    foo() noexcept = default; // no error w/o this line 
}; 

然而析构函数来解决,这是我不明白为什么/这是否是标准要求的。

+1

增加了'〜bar()= default;'vs'〜bar(){}':'〜bar'的好处,它不是当它是用户定义的时候(即使是空的)。 –

3

这是一个叮咚的bug。但是有一个简单的解决方法。

当一个限定为缺省的一个特殊的成员函数,所述noexcept符只是用于检查由编译器生成的默认的特殊构件将noexcept[dcl.sft.dcl.def]

如果函数是明确默认声明与 noexcept说明符 不会产生相同的 异常规范的隐式声明(18.4),然后

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

- 否则,该程序是不合格的。

所以,如果你删除的foo默认构造函数的noexcept sepcifier,你会不会改变语义,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); 
+0

如果这是一个已知的叮当声,那么必须有一个可引用的入口到相应的bug库。你能提供一个链接吗? – Walter

+0

实际上,这是因为它的行为不一致而造成的一个叮当声错误:如果在这两种情况下默认构造函数都是noexcept,它不应该依赖noexcept说明符。为什么我不会检查或填写叮当的错误?我的财产概念遵循罗马式的权利:一个领域属于农场的领域。所以铿锵是谷歌的财产,我不会为他们免费工作!你可以做到这一点,这不是我的事。 – Oliv

+1

你是多么的错。 Clang是开源的,谷歌只是贡献者之一,其他的则包括苹果,微软,AMD,ARM,索尼,英特尔。 – Walter

相关问题