假设我有一个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 ++不允许我首先尝试做的事情,在这种情况下是否有一个很好的成语可以完成同样的事情?显式模板专业化 没有存储类
答案 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
我的计划