Проблемы частичной специализации шаблона

Я пытаюсь написать универсальный векторный класс размера и типа для математического программирования. У меня проблемы с частичной специализацией.

Проблема возникает, когда я пытаюсь специализировать метод-член моего векторного класса для заданного размера.

Я могу привести простой пример:

template <size_t Size, typename Type>
class TestVector
{
public:
inline TestVector (){}
TestVector cross (TestVector const& other) const;
};

template < typename Type >
inline TestVector< 3, Type > TestVector< 3, Type >::cross (TestVector< 3, Type > const& other) const
{
return TestVector< 3, Type >();
}

void test ()
{
TestVector< 3, double > vec0;
TestVector< 3, double > vec1;
vec0.cross(vec1);
}

При попытке скомпилировать этот простой пример я получаю ошибку компиляции, утверждающую, что специализация ‘cross’ не соответствует существующему объявлению:

error C2244: 'TestVector<Size,Type>::cross' : unable to match function definition to an existing declaration
see declaration of 'TestVector<Size,Type>::cross'
definition
'TestVector<3,Type> TestVector<3,Type>::cross(const TestVector<3,Type> &) const'
existing declarations
'TestVector<Size,Type> TestVector<Size,Type>::cross(const TestVector<Size,Type> &) const'

Я попытался объявить крест в качестве шаблона:

template <size_t Size, typename Type>
class TestVector
{
public:
inline TestVector (){}

template < class OtherVec >
TestVector cross (OtherVec const& other) const;
};

template < typename Type >
TestVector< 3, Type > TestVector< 3, Type >::cross< TestVector< 3, Type > > (TestVector< 3, Type > const& other) const
{
return TestVector< 3, Type >();
}

Эта версия проходит компиляцию, но терпит неудачу во время соединения:

 unresolved external symbol "public: class TestVector<3,double> __thiscall TestVector<3,double>::cross<class TestVector<3,double> >(class TestVector<3,double> const &)const

Что мне здесь не хватает?
Спасибо,
Флоран

4

Решение

Один из способов сделать это — определить cross как «функтор» (то есть класс с operator()).

template<size_t S, typename T>
class Vec {
// ... stuff
friend struct Cross<S, T>;
Vec<S, T> cross(const Vec<S, T>& other) {
return Cross<S, T>()(*this, other);
}
// ... more stuff
};template<size_t S, typename T> struct Cross {
Vec<S, T> operator() (const Vec<S, T>& a, const Vec<S, T>& b) {
// general definition
}
};

// Partial specialization
template<typename T> struct Cross<3, T> {
vec<3, T> operator() (const Vec<3, T>& a, const Vec<3, T>& b) {
// specialize definition
}
};
1

Другие решения

Вы не можете частично специализировать метод. Вы можете перегружать при определенных условиях. Здесь вы можете пойти с частичной специализацией вашего класса

template <size_t Size, typename Type> class TestVector
{
public:
inline TestVector (){}
TestVector cross (TestVector const& other) const;
};

с определением общего поведения:

TestVector<size_t Size, typename Type>::cross (TestVector const& other) const {
// general
}

и специальный шаблон, который позволит вам определить конкретное поведение для случая int 3

template <typename Type> class TestVector<3, Type>
{
public:
inline TestVector (){}
TestVector cross (TestVector const& other) const;
};

с определением для пользовательского поведения:

TestVector<typename Type>::cross (TestVector const& other) const {
// custom
}
0

По вопросам рекламы [email protected]