Явная специализация в области без пространства имен
template<typename T>
class CConstraint
{
public:
CConstraint()
{
}
virtual ~CConstraint()
{
}
template <typename TL>
void Verify(int position, int constraints[])
{
}
template <>
void Verify<int>(int, int[])
{
}
};
Компиляция в g++ дает следующую ошибку:
Явная специализация в области без пространства имен 'class CConstraint'
В VC он компилируется отлично. Может кто-нибудь, пожалуйста, дайте мне знать обходной путь?
Ответы
Ответ 1
В этом случае VС++ несовместим - явные специализации должны быть в области пространства имен. С++ 03, §14.7.3/2:
Явная специализация объявляется в пространстве имен, членом которого является шаблон, или для шаблонов-членов в пространстве имен, членом которого является класс-оболочка или закрытый шаблон класса.
Явная специализация функции-члена, класса-члена или статического элемента данных шаблона класса объявляется в пространстве имен, членом которого является шаблон класса.
Кроме того, у вас возникла проблема, заключающаяся в том, что вы не можете специализировать функции-члены без явной специализации класса-класса из-за С++ 03, §14.7.3/3, поэтому одним из решений было бы позволить Verify()
переслать a, возможно специализированная, свободная функция:
namespace detail {
template <typename TL> void Verify (int, int[]) {}
template <> void Verify<int>(int, int[]) {}
}
template<typename T> class CConstraint {
// ...
template <typename TL> void Verify(int position, int constraints[]) {
detail::Verify<TL>(position, constraints);
}
};
Ответ 2
Другим способом решения этой проблемы является делегирование частной функции и перегрузка этой функции. Таким образом, у вас все еще есть доступ к данным элемента *this
и к типу параметра внешнего шаблона.
template<typename T>
struct identity { typedef T type; };
template<typename T>
class CConstraint
{
public:
template <typename TL>
void Verify(int position, int constraints[])
{
Verify(position, constraints, identity<TL>());
}
private:
template<typename TL>
void Verify(int, int[], identity<TL>)
{
}
void Verify(int, int[], identity<int>)
{
}
};
Ответ 3
Просто возьмите специализацию шаблона вне объявления класса.
gcc не разрешает специализированную специализированную специализацию.
В качестве другого варианта просто удалите строку
Шаблон < > кажется, работает для меня.
Ответ 4
Еще лучше: вы можете объединить частичную специализацию с аргументами шаблона по умолчанию. Таким образом, модификация кода VС++ незначительна, так как вызовы специализированной функции не нуждаются в изменении.
template <typename TL, class Dummy=int>
void Verify(int position, int constraints[])
{
}
template <class Dummy=int>
void Verify<int, Dummy>(int, int[])
{
}
Ответ 5
Возможно, вы не сможете явно специализировать шаблон-член, но вы можете частично его специализировать. Если вы добавите второй параметр "int dummyParam", а также добавьте его в специализацию, он должен работать с обоими компиляторами.
Не то чтобы я знал это больше, чем 10 секунд назад, но искал ту же ошибку, я столкнулся с этой ссылкой, и это сработало для моего специализация шаблона участника.