Я надеюсь, что кто-то может указать правильный способ специализировать метод в классе шаблона, используя "внешний шаблонный класс" и "шаблонный класс" для явного создания экземпляра с помощью gnu c ++.Я попытался свести эту проблему к простейшему примеру, который имитирует мою настоящую проблему.Похоже, что объявление «внешнего шаблона» подразумевает создание шаблона, что приводит к ошибкам при специализации методов.Имеется драйвер программы:
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
ah
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
%
Если я закомментирую две строки «внешнего шаблона» в ах, все скомпилируетсяи работать как ожидается с обоими компиляторами.Я предполагаю, что в зависимости от существования явного создания экземпляра при отсутствии «внешнего шаблона» поведение не определено даже в C ++ 0x, в противном случае, какой смысл в C ++ 0x добавление «внешнего шаблона»?
Если я вместо этого реализую A как:
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 ().
Я понимаю, что явное создание экземпляра шаблона не является стандартным на данном этапе, но кто-то может ожидатьчто я сделал выше, чтобы работать?Если нет, то как правильно это сделать?
Спасибо