Inheriting from a specialized self-government class?

Is this valid C ++?

template<class category> class any_iterator : public any_iterator<void> { public: typedef any_iterator<void> any_iter_void; any_iterator() : any_iter_void() {} }; template<> class any_iterator<void> { public: typedef any_iterator<void> any_iter_void; any_iterator() {} void foo() {}; }; int main() { any_iterator<int> a; a.foo(); } 

MSVC10 accepts it without errors / warnings on \WALL , but gcc-4.5.1 complains:

prog.cpp: 3: 5: error: incorrect use of the incomplete type "class any_iterator"
prog.cpp: 2: 11: error: class declaration any_iterator

prog.cpp: In the function 'int main ()':
prog.cpp: 21:11: error: "class any_iterator" does not have a name with the name "foo"
prog.cpp: In the constructor any_iterator :: any_iterator () [with category = int] ':
prog.cpp: 20: 27: created here
prog.cpp: 7:44: error: type 'any_iterator' is not a direct base of 'any_iterator'

Can someone quote the standard version if this should or should not be compiled? I think this is a bug in MSVC.

As a note, I know that the right thing is to declare a class, specialize the root, then determine the general case and what I will do with my code, but I was wondering which compiler is wrong here

+4
source share
2 answers

To inherit from a type, this type must be complete. A small permutation solves everything:

 template<class category> class any_iterator; template<> class any_iterator<void> { public: typedef any_iterator<void> any_iter_void; any_iterator() { } void foo() { } }; template<class category> class any_iterator : public any_iterator<void> { public: typedef any_iterator<void> any_iter_void; any_iterator() : any_iter_void() { } }; int main() { any_iterator<int> a; a.foo(); } 

Standard token quotes:

C ++ 11, ยง10 / 2:

The type indicated by the base type specifier must be a class type, which is not a fully defined class; this class is called the direct base class for the class being defined.

ยง9.2 / 2:

A class is considered a fully defined object type (or full type) when closing } the class specifier.

+4
source

10/2:

The type denoted by the specification of the base type must be the type of a class that is not an incompletely defined class

This is one manifestation of the MSVC error: lack of two-phase name resolution.

0
source

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


All Articles