Search code examples
c++c++20template-meta-programminglinkage

Why is an external template redeclared as a "different kind of entity"?


So I'm trying to share a templated global variable between translational units.

There is a common strategy to do this for functions where you have one header declaring/implementing the template and second C++ file that explicitly enumerates all arguments to actually generate the code for the linker.

The original version looks like

template<typename T>
struct PoolType
{
    void do_something()
    {

    }
};

template <class T>  PoolType<T> pool;

int main ()
{
    pool<int>.do_something(); 
    pool<float>.do_something();// can make other types 
}

I'm getting some strange error when extending this approach to templated structures. Does anybody know what the error means and which kind of entity is "declared"?

template<typename T>
struct PoolType
{
    void do_something()
    {

    }
};

template <class T>  extern PoolType<int> pool; //Suppoedly can live in another TU
//In some other file
PoolType<int> pool;

// template <class T>  PoolType<int> pool; //works fine but limited to one TU
int main ()
{
    pool<int>.do_something(); 
}

gcc

 error: 'PoolType<int> pool' redeclared as different kind of entity

clang

error: redefinition of 'pool' as different kind of symbol

on godbolt


Solution

  • You can do one of the two things.

    1. Make pool a normal variable.

      extern PoolType<int> pool;
      // in some other file
      PoolType<int> pool;
      // in main
      pool.do_something();
      
    2. Make pool a variable template.

      template <class T> extern PoolType<T> pool;
      // in some other file
      template <> PoolType<int> pool<int>;
      // in main
      pool<int>.do_something();