显式模板专用化错误

Explicit template specialization error

本文关键字:错误 专用      更新时间:2023-10-16

这个应该很容易。我正在使用模板,但收到编译器错误。

#include <iostream>
template <class T1, class T2>
class Pair
{
    private:
        T1 a;
        T2 b;
    public:
        T1& first();
        T2& second();
        Pair(const T1& aval, const T2& bval) : a(aval), b(bval) {}
};
template <class T1, class T2>
T1& Pair<T1,T2>::first()
{
    return a;
}

template <class T1, class T2>
T2& Pair<T1,T2>::second()
{
    return b;
}
// Explicit Specialization
template <>
class Pair<double, int>
{
    private:
        double a;
        int b;
    public:
        double& first();
        int& second();
        Pair(const double& aval, const int& bval) : a(aval), b(bval) {}
};
template <>
double& Pair<double,int>::first()
{
    return a;
}
template <>
int& Pair<double,int>::second()
{
    return b;
}

int main(int argc, char const *argv[])
{
    Pair<int, int> pair(5,6);
    //Pair<double,int> pairSpec(43.2, 5);
    return 0;
}

错误如下所示

main.cpp:42:27: error: no function template matches function template specialization 'first'
double& Pair<double,int>::first()
                          ^
main.cpp:49:24: error: no function template matches function template specialization 'second'
int& Pair<double,int>::second()

有什么线索可以发现可能出现什么问题吗?

在方法声明之前不需要模板<>声明。

double& Pair<double,int>::first() {
    return a;
}
int& Pair<double,int>::second() {
   return b;
}

应该足够了。

由于另一个答案没有解释为什么这里不需要前缀 template<>,我将尝试在我的答案中提供该解释。

问题的解决方案

如下所述,我们只需要删除template<>前缀,如下所示:

//no prefix template<> needed here
inline double& Pair<double,int>::first()
{
    return a;
}
//no prefix template<> needed here
inline int& Pair<double,int>::second()
{
    return b;
}

工作演示

请注意,添加了 inline 关键字,这样我们就不会收到多个定义错误,因为通常我们在头文件中实现模板,然后包含在多个源文件中。

问题解释

我们不需要前缀template<>的原因是,我们为完整类模板专用化的成员函数提供了一个普通的类外定义。也就是说,我们实际上并没有专门研究成员函数,而是为这些成员函数提供了一个普通的(非模板)类外定义。