c ++函数模板专业化

时间:2011-10-12 10:45:06

标签: c++ templates template-specialization

鉴于此代码:

class X
{
public:
    template< typename T >
    void func( const T & v );
};

template<>
void X::func< int >( const int & v )
{
}

template<>
void X::func< char * >( const char * & v )       // 16
{
}

当我编译它时,我收到以下错误。

test.cpp:16: error: template-id 'func<char*>' for 'void X::func(const char*&)' does not match any template declaration

任何人都可以对此有所了解吗?

3 个答案:

答案 0 :(得分:7)

如果您更改声明:

template<> void X::func< char * >( const char * & v )

为:

template<> void X::func< char * >( char * const & v )

这将完美无缺。为什么会这样?因为虽然const sometype完全可以接受,但它只是sometype const的替代符号。因此,你的const修饰符不适用于基本类型(char),而是应用于指针,使“常量指针指向非常量字符”成为有效类型。如果那不是你想要的,你将不得不纠正你的基本模板。

最后,这里有一些关于why overloading templates is generally better than specializing them的有趣读物。

答案 1 :(得分:4)

const

之前移动&
template<> 
void X::func< char * >( char * const & v ) 
{ 
} 

答案 2 :(得分:4)

您遇到此错误的原因是您在类型之前编写const。虽然这是常见的做法,但它不利于理解const / volatile-qualifiers(cv-qualifier)如何工作。

在这种情况下,const T T char*const char*并不代表char* const。它更像是T,因为char*T,无论你放置const const的哪一边,T的行为就好像const一样volatile的权利,也就是说,指针本身将是const而不是指向的类型。

如果您规定始终将T constT放在该类型的右侧,则很容易避免此类混淆。例如,当char*char* const为{{1}}时,它可以直接在心理上扩展{{1}}。

这就是你在升级源中看到类型之后的cv-qualifiers的原因,而不是之前。