blazee
blazee

Reputation: 378

Function template instantiation using an incomplete type

Is the following (in)correct c++ code and why?

class MyC;
class MyB {
public:
     template <class MyT> static void Gimme() { MyT(); }
     MyB() { Gimme<MyC>(); }
} B_;

class MyC  {
public: MyC() { }
};

g++ 4.7.2 does not complain.

Upvotes: 3

Views: 573

Answers (2)

AnT stands with Russia
AnT stands with Russia

Reputation: 320401

I'd guess that the following portion of C++14 standard is at work here

14.6.4.1 Point of instantiation

8 A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. [...]

(Emphasis mine.)

Note that this portion of document was changed significantly in C++14 compared to C++11. Also see DR#993, which seems to imply that simply postponing such instantiations to the end of translation unit is a valid implementation technique.

I would go as far as cautiously state that your code is ill-formed under C++11 instantiation rules, even though GCC accepts it in -std=c++11 mode.

Upvotes: 4

ul90
ul90

Reputation: 787

Yes, this is legal C++ code. You declare MyC as forward declaration, and the definition is in the same scope later. And because the C++ compiler uses at least 2 passes to parse the source files, this is correct and will generate correct machine code. Your "incomplete" type MyC is not incomplete.

Upvotes: -1

Related Questions