jeudi 28 janvier 2021

extern template declaration with alias payload

Consider this. There is a class Derived that inherits from some instantiation of a heavy templated class Base, and there are many uses of Derived in various source files. So it is reasonable to have only one Derived-specific instantiation of Base.

C++11 allows this via extern template, but the problem here is that I want to type the Derived-specific instantiation of Base only once. Technically it is possible, as Derived can hold an alias for that instantiation, but the question is: will it still force the compiler not to instantiate the template?

Here is the try:

// Base.hpp
template < typename Arg > struct Base { using TheArg = Arg; };

// Derived.hpp
#include "Base.hpp"
struct Derived : Base<int> { };
// The next line will be huge in real-world scenario, so I want to avoid it.
// extern template struct Base<int>;
// Instead I want this.
extern template struct Base<Derived::TheArg>;

// Derived.cpp
#include "Derived.hpp"
template struct Base<Derived::TheArg>;

// Use01.cpp
#include "Derived.hpp"
void use01() { Derived dd; }

The point here is to force Use01.cpp not to instantiate Base<int> and to refer to the explicit instantiation at Derived.cpp instead.

I am compiling with gcc-v9.3 and the questions are:

  1. Does extern template declaration takes effect to all instantiations in the translation unit, or only to those which appear after its declaration?
  2. Will using Derived::TheArg instead of int cause any problems with deferring the instantiation?

Putting the extern template declaration at the end of Use01.cpp and commenting out the explicit instantiation at Derived.cpp makes the compilation to fail, so this gives me some confidence that the extern template declaration doesn't have to appear before any instantiation, so the second question still makes sense.

Aucun commentaire:

Enregistrer un commentaire