C++ CRTP virtual function point of instantiation

前端 未结 2 766
长发绾君心
长发绾君心 2021-01-11 11:51

I\'m trying to understand if a simple CRTP pattern is valid by the standard.

The code below compiles and works as expected (on clang).

But my understanding o

2条回答
  •  走了就别回头了
    2021-01-11 12:52

    The use of new Derived causes the Derived class to be instantiated.

    Correction: Derived is not itself a template, so its structure layout and contained member declarations are needed right away. That causes CRTP to be instantiated immediately following the Derived definition. I'll have to look up the formal standard later when I have more time; but the the point is still that the instantiation of CRTP only figures out the structure and available members, not the bodies of the member functions; and it knows the structure and members of the Derived class when it does so.

    The member functions are not instantiated until they are used (here, the constructor), and it already has the class itself at that time. The other thing to look up is whether the constructor of Derived, since it is not a template, is generated immediately following the class, or only if/when needed. If the former, it can be made lazy by making Derived a template with a dummy argument. But that doesn't affect this specific question: whether right after Derived or right after main, the function instantiation is still not before parsing the declaration of Derived.

    That causes CRTP to be instantiated. But in both cases it is only the class structure that is needed, not the actual code for any of the members. Erase all the inline function bodies, and you'll see there is no problem at this point.

    Now the Derived default constructor is used, so Derived::Derived() is implicitly instantiated. The point of instantiation is immediately following the definition of main.

    In instantiating Derived::Derived(), it then needs CRTP::CRTP(). It is instantiated at the same point as the template instantiation that needed it. That constructor needs all the virtual functions, so DoSomething() is instantiated, again, at the same point as the instantiation that kicked it off. You can see that all this happens well after the complete definition of the fully rendered Derived class is known, in terms of all the declarations of all the members (not the function bodies).

    That's the missing insight: the class definition does not include member function definitions, even if they are given within the lexical enclosing region of the class definition. Remember the distinction between definitions and declarations, separately for classes and functions.

提交回复
热议问题