Given this code:
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
{
}
When I compile it I get the following error.
test.cpp:16: error: template-id 'func<char*>' for 'void X::func(const char*&)' does not match any template declaration
Can anyone shed any light on this?
Move
const
before&
If you change the declaration:
to:
This would work perfectly fine. Why does it happen? Because while
const sometype
is perfectly acceptable, it's only an alternative notation forsometype const
. So, your const modifier is not applied to the basic type (char
), but to the pointer, making "constant pointer to non-constant char" a valid type. If that's not what you want, you'll have to correct your basic template.Finally, here's some interesting reading for you about why overloading templates is generally better than specializing them.
The reason you face this error is because you write
const
before the type. Although this is common practise, it is not conducive to understanding how const/volatile-qualifiers (cv-qualifier) work.In this case
const T
whenT
ischar*
doesn't meanconst char*
. It rather meanschar* const
becauseT
ischar*
and no matter which side ofT
you putconst
it behaves as ifconst
is on the right ofT
, that is, the pointer itself that is going to be const not the type pointed too.It is easy to avoid this type of confusion if you make it a rule to always put
const
orvolatile
on the right of the type. For example, it makes it straightforward to mentally expandT const
whenT
ischar*
tochar* const
.This is the reason in boost sources you see cv-qualifiers after the type, not before.