如何专门化非模板类的模板成员函数?

时间:2010-07-16 16:16:01

标签: c++ templates template-specialization

假设我有一个alpha.h文件:

class Alpha {
public:
    template<typename T> void foo();
};

template<> void Alpha::foo<int>() {}
template<> void Alpha::foo<float>() {}

如果我将alpha.h包含在多个cpp文件中并使用GCC 4.4进行编译,则会抱怨多个目标文件中有foo<int>foo<float>的多个定义。对我有意义,所以我将最后两行更改为:

template<> extern void Alpha::foo<int>() {}
template<> extern void Alpha::foo<float>() {}

但GCC说:

  

显式模板专业化   没有存储类

好的......所以我该如何正确地做到这一点?我担心C ++不允许我首先尝试做的事情,在这种情况下是否有一个很好的成语可以完成同样的事情?

4 个答案:

答案 0 :(得分:10)

使用内联关键字

template<> inline void Alpha::foo<int>() {}

或者,在单独的cpp文件中提供实现

答案 1 :(得分:6)

您可以转发声明以及内联选项:

// .h
template<> void Alpha::foo<int>();

//.cpp
template<> void Alpha::foo<int>() {}

答案 2 :(得分:4)

从ODR的角度来看,完全(显式)专用模板不再是模板,因此它与相同类型的非模板实体具有相同的ODR原则。 (我相信,该规则有一些例外情况,但对我们的目的来说已经足够了。)

在您的情况下,对于ODR目的,完全专用的函数模板是普通函数。因此,作为普通函数,它应该在头文件中声明,并且在一个且只有一个实现文件中定义

答案 3 :(得分:-1)

无需单独声明或内联键工作。 PF低于工作代码。

#include<iostream>

class temp
{
public:
    template <class T>
    T add1(T a, T b)
    {
            return (a + b);
    }
};

template<>
std::string temp::add1<std::string>(std::string aa, std::string bb)
{
    return aa+bb;
}

int main()
{
    temp *tc = new temp();
    std::cout << tc->add1<float>(5.7, 4.5) << std::endl;
    std::cout << tc->add1<std::string>("my ","program") << std::endl;
}

输出是:

  

10.2

     

我的计划