Can a derived type be the same name as its nested base type?

Is the following code legal? MSVC 9 and g ++ 4.4 disagree:

struct base { struct derived {}; }; struct derived : base {}; int main() { typedef derived::derived type; return 0; } 

MSVC complains, confusing the nested name for the type constructor:

 c:\dev>cl test.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. test.cpp test.cpp(10) : error C2146: syntax error : missing ';' before identifier 'type' test.cpp(10) : error C2761: '{ctor}' : member function redeclaration not allowed test.cpp(10) : error C2065: 'type' : undeclared identifier 

So far g ++ does not:

 $ g++ --version test.cpp g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

In context, my code contains a pointer iterator. To provide an iterator interface, it provides a nested pointer type, which is a synonym for itself.

+4
source share
2 answers

Comeau believes that your code is incorrect, so I believe that constructor interpretation that obscures the type interpretation conforms to standard 1 .

However, your code will happily compile if you remove the ambiguity and tell the compiler that you are trying to access the derived element of the base class:

 struct base { struct derived {}; }; struct derived : base {}; int main() { typedef derived::base::derived type; return 0; } 

By the way, the fact that constructor-interpretation prevails makes sense: you have a well-known way of telling the compiler that you want to refer to the base class material (via the region resolution operator), but you would not have the syntax for the opposite (to make the compiler understand that you are referring to the constructor). Therefore, the default constructor behavior seems reasonable.


  • I can watch it later, but I can’t guarantee that I will actually do it, such nasty problems with names are always useless for searching.
+3
source

You have a conflict in names. Just rename the second structure to struct derived2 . And make this change in main() too: typedef derived2::derived type; It compiles without errors in VC ++ 6.0

 struct base { struct derived {}; }; struct derived2 : base {}; int main() { typedef derived2::derived type; return 0; } 
0
source

Source: https://habr.com/ru/post/1385022/


All Articles