鉴于此代码:
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
任何人都可以对此有所了解吗?
答案 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 const
或T
放在该类型的右侧,则很容易避免此类混淆。例如,当char*
为char* const
为{{1}}时,它可以直接在心理上扩展{{1}}。
这就是你在升级源中看到类型之后的cv-qualifiers的原因,而不是之前。