Почему я получаю пропущенные символы для явной специализации шаблона в статической библиотеке?

StackOverflow https://stackoverflow.com/questions/3989435

Вопрос

Если я составлю следующий код:

//
// g++ static.cpp -o static.o
// ar rcs libstatic.a static.o
//
#include <iostream>

template < typename T >
struct TemplatedClass
{
  void Test( T value )
  {
    std::cout << "Foobar was: " << value << std::endl;
  }
};

template struct TemplatedClass < long >;

Я получаю статическую библиотеку, и если я запускаю NM в библиотеке, я получаю следующие результаты:

testcase% nm libstatic.a | c++filt | grep TemplatedClass
0000000000000207 s global constructors keyed to _ZN14TemplatedClassIlE4TestEl
0000000000000300 s global constructors keyed to _ZN14TemplatedClassIlE4TestEl.eh
0000000000000118 T TemplatedClass<long>::Test(long)
00000000000002a0 S __ZN14TemplatedClassIlE4TestEl.eh

Однако, если я составляю следующий код, который такой же, за исключением того, что я добавил явную специализацию шаблонного класса ...

//
// g++ static.cpp -o static.o
// ar rcs libstatic.a static.o
//
#include <iostream>

template < typename T >
struct TemplatedClass
{
  void Test( T value )
  {
    std::cout << "Foobar was: " << value << std::endl;
  }
};

template <>
struct TemplatedClass < long >
{
  void Test( long value )
  {
     std::cout << "Value was: " << value << std::endl;
  }
}; 

template struct TemplatedClass < long >;

... и повторить ту же команду:

testcase% nm libstatic.a | c++filt| grep TemplatedClass
testcase% 

Я не получаю соответствующих символов. По какой -то причине компилятор не создает экземпляры шаблона, хотя я явно просил об этом.

Кто -нибудь может объяснить мне, что здесь происходит?

Это было полезно?

Решение

У вас есть определения функций члена в определениях класса (шаблон). Это заставляет функции члена (шаблоны) быть inline. Анкет Это не имеет большого значения для функции члена класса шаблонов, поскольку его требования к сцеплению определяются в большей степени по характеру его экземпляров.

Но во втором примере функция члена void TemplatedClass<long>::Test(long) не является шаблоном функции и все еще inline. Анкет Таким образом, компилятор не обязан ничего делать с ним, если он не используется, и он должен быть определен во всех файлах, где он используется. Поскольку вы утверждаете, что это в файле static.cpp, встроенная функция, вероятно, не то, что вы хотите.

Я думаю, что вы получите результаты, как и ожидаете, если измените что -то:

template <>
struct TemplatedClass < long >
{
  void Test( long value );
};

void TemplatedClass<long>::Test( long value )
{
  std::cout << "Value was: " << value << std::endl;
}

И когда вы определяете явную специализацию, вам, вероятно, также не нужна явная экземпляра (если это даже законно).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top