Я надеюсь, что кто-то может указать правильный способ специализации метода в классе шаблона при использовании "extern template class" и "template class" для явного создания экземпляра с помощью gnu С++. Я попытался свести эту проблему с простейшим примером, который подражает моей реальной проблеме. По-видимому, объявление "шаблона extern" подразумевает создание шаблона, которое вызывает ошибки при специализированных методах. С учетом программы драйвера:
main.cc
#include A_H
#include <iostream>
int main()
{
A<int> ai;
A<long> al;
std::cout << "ai=" << ai.get() << " al=" << al.get() << std::endl;
return 0;
}
И следующая реализация A
хиджры
template<typename T>
struct A
{
int get() const;
};
extern template class A<int>;
extern template class A<long>;
a.cc
#include "a.h"
template<typename T>
int A<T>::get() const
{
return 0;
}
template<>
int A<long>::get() const
{
return 1;
}
template class A<int>;
template class A<long>;
Я получаю следующую ошибку при компиляции с помощью: g++ 4.1.2 или 4.4.4
% g++ -Wall -g -D'A_H="a.h"' a.cc main.cc
a.cc:10: error: specialization of 'int A<T>::get() const [with T = long int]' after instantiation
%
Если я прокомментирую две строки "extern template" в a.h, вещи компилируются и работают как ожидалось с обоими компиляторами. Я предполагаю, что в зависимости от существования явного экземпляра в отсутствие "шаблона extern" это неопределенное поведение даже в С++ 0x, в противном случае, что точка С++ 0x, добавляющая "шаблон extern"?
Если я вместо этого реализую A как:
а-hack.h
template<typename T>
struct A
{
int get() const;
};
template<typename T>
int A<T>::get() const
{
return 0;
}
template<>
inline
int A<long>::get() const
{
return 1;
}
extern template class A<int>;
extern template class A<long>;
a-hack.cc
#include "a-hack.h"
template class A<int>;
template class A<long>;
и скомпилировать снова, это работает как ожидалось
% g++ -Wall -g -D'A_H="a-hack.h"' a-hack.cc main.cc
% ./a.out
ai=0 al=1
Тем не менее, в моем реальном примере это приводит к сбою программы с g++ 4.1.2 (при работе для g++ 4.4.4). Я не сузил точную причину аварии (ошибка сегментации). Он появляется только в том случае, если указатель стека поврежден в том, что было бы вызовом A < > :: get().
Я понимаю, что явное создание шаблона не является стандартным на данный момент, но ожидал ли кто-нибудь, что я сделал выше, чтобы работать? Если нет, то каков правильный способ сделать это?
Спасибо