2010-07-16 171 views
4

假设我有一个文件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++不允许我想要做的事情,在这种情况下是否有一个很好的习惯用法可以完成同样的事情?

+2

您可以使用 '内联'? – sje397 2010-07-16 16:18:07

回答

9

使用inline关键字

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

另外,提供实施在单独的cpp文件

+0

完美,谢谢 – Kyle 2010-07-16 16:23:32

+1

如果你已经有'static inline',就移除'static'。 – 2013-10-25 13:35:04

6

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

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

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

从视ODR点,完全(明确)专用的模板不再是模板,因此它与同一类型的非模板实体一样遵循相同的ODR原则。 (我相信,这条规则有一些例外,但对我们的目的来说已经足够了)。

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

-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

我的程序

+1

当然,如果你有一个文件中的所有东西......但这不是OP的问题,他有多个对象文件的问题。即他想知道如何在多个编译单元中使用头文件时使其工作。 – Cilyan 2016-05-24 17:49:43