模板偏特化问题

4
我正在尝试编写一个数学编程通用大小和类型向量类。我在部分特化方面遇到了问题。
当我尝试为给定的大小专门设计向量类成员方法时,问题就出现了。
下面是一个简单的例子:
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'

我尝试声明cross为一个模板:

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

我这里缺少什么吗? 谢谢, Florent


1
一个问题是你没有部分特化class,而是在其中某个函数上进行了特化,这里的class模板化的,因此部分特化应该是另一个类模板。 - Tony The Lion
@TonyTheLion 谢谢,你的意思是我应该专门化整个Vector类吗?我的问题是这将需要我重新编写整个类(它包含许多方法,不仅仅是cross)。 - F.L.
1
问题已经被问过了。请查看这个答案:https://dev59.com/2GvXa4cB1Zd3GeqPEwKg#13444841 - Synxis
2个回答

1
一种实现这个的方法是将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
  }
};

谢谢,这是我选择的选项。但是提供的代码有一个小错误,操作符()需要两个参数;) - F.L.
@F.L. 啊,抱歉。已修复。谢谢。 - rici

0

你不能部分特化一个方法。在某些条件下,你可以进行重载。在这里,你可以使用类的部分特化。

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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接