It started with an observation. I changed the code that looks a bit like this (edit: I pulled out the designated initializers here that were also not in the source code):
struct S {
enum E { E1, E2 } member;
}
S v1 = { S::E1 };
S v2 = { S::S::E2 };
Note that file2.cc
over-qualifies E2
. However, this works in both g ++ and clang ++. (Change 2: g ++ on this particular virtual machine - g ++ - 5.4.1, but the source code went through earlier and later versions of g ++, as well as several versions of clang.) Indeed, we can write:
S v3 = { S::S::S::S::S::S::S::E1 };
( S::
), . , S
struct
, , . , , .
-POD-:
struct S {
S() { std::cout << "made an S" << std::endl; }
enum E { E1, E2 } member;
}
( #include
) . Clang g++ . clang:
namespace.cc:8:3: error: no matching constructor for initialization of 'S'
S x = { .member = S::S::E1 };
namespace.cc:3:8: note: candidate constructor (the implicit copy constructor)
not viable: cannot convert argument of incomplete type 'void' to
'const S &' for 1st argument
struct S {
^
namespace.cc:3:8: note: candidate constructor (the implicit move constructor)
not viable: cannot convert argument of incomplete type 'void' to &&'
for 1st argument
struct S {
^
namespace.cc:4:3: note: candidate constructor not viable: requires 0 arguments,
but 1 was provided
S() { std::cout << "made an S\n"; }
^
1 error generated.
g++:
namespace.cc:8:28: error: could not convert ‘{E1}’ from ‘<brace-enclosed initializer list>’ to ‘S’
S x = { .member = S::S::E1 };
, . ?
, . :
#include <iostream>
struct S {
S() { std::cout << "made an S\n"; }
enum E { E1, E2 } member;
};
int main() {
std::cout << S::S::S::S::S::E1 << std::endl;
#ifdef DECL
S::S::S var;
#endif
return 0;
}
( -DDECL
) :
$ clang++-3.9 -std=c++11 -Wall -O namespace.cc
$ ./a.out
0
$ g++ -Wall -std=c++11 -O namespace.cc
$ ./a.out
0
(No S
, , clang member
.) main
, , g++, clang
$ clang++-3.9 -std=c++11 -DDECL -Wall -O namespace.cc
$ ./a.out
0
made an S
$ g++ -std=c++11 -DDECL -Wall -O namespace.cc
namespace.cc: In function ‘int main()’:
namespace.cc:11:3: error: ‘S::S’ names the constructor, not the type
S::S::S var;
^
namespace.cc:11:11: error: expected ‘;’ before ‘var’
S::S::S var;
^
namespace.cc:11:14: error: statement cannot resolve address of overloaded function
S::S::S var;
^
, ? "" ?