Consider this snippet:
struct S {
template <typename T>
void insert(const T& x);
};
template <>
void S::insert<char*>(const char*& x) {}
int main() {
S s;
s.insert("");
return 0;
}
gcc fails to compile it with the following error message:
error: template-id 'insert<char*>' for 'void S::insert(const char*&)' does not match any template declaration
What's the reason for this error, and is there a way to write the specialization such that it will work?
I'm not looking for an alternative solution, I'm simply trying to understand the logic behind the error.
You specify wrong parameter type.
Note that for const T&
, const
is qualified on T
itself. Then for T
= char*
, const T&
should be char* const &
(i.e. reference to const
pointer), not const char* &
(i.e. reference to pointer to const
).
BTW Clang gives more clear error message:
candidate template ignored: could not match 'void (char *const &)' against 'void (const char *&)'
BTW again, for s.insert("");
the specification won't be invoked because ""
is a const char[1]
indeed, then the type for T
will be deduced as char [1]
, which doesn't match char *
. If you want the specification works with char[1]
, then it should be
template <>
void S::insert<char[1]>(char const (&) [1]) {}
then
S s;
s.insert("");
But it only works with char[1]
, i.e. the char
array with only one element. I think make it work with const char*
would make more sense, then it should be
template <>
void S::insert<const char*>(const char * const &) {}
then
S s;
const char* str = "";
s.insert(str);