"The default element initializer needed to determine the inclusion class outside member functions" - is my code poorly formed?

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

Yes, I know, there is one more question with exactly the same name, but a slightly different problem (involving the noexcept operator and no nested type). Proposed Solution (replacing the foo constructor with

  foo() noexcept {} 

) changes the semantics, and here it is not needed: here we have a better answer (therefore, the question is not a duplicate).

: 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; ^ 
+7
c ++ language-lawyer c ++ 11 noexcept inner-classes
source share
2 answers

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

When a special member function is defined as default, the noexcept used only to verify that the default special member generated by the compiler will be noexcept , [dcl.sft.dcl.def] :

If a function explicitly specified by default is declared using the noexcept specifier, which does not give the same exception specification as an implicit declaration (18.4) , then

- if the function is clearly defaulted by the first declaration, it is defined as deleted;

- otherwise the program is poorly formed.

So, if you remove the noexcept sepcifier of the default constructor foo , you will not change the semantics, foo will still be constructive by default:

 #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); 
+3
source share

The problem can be solved by default with the destructor of the nested class

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

However, it is not clear to me why / whether this is required by standard.

+1
source share

All Articles