Явная специализация в области без пространства имен

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 секунд назад, но искал ту же ошибку, я столкнулся с этой ссылкой, и это сработало для моего специализация шаблона участника.