Reputation: 4500
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.
Upvotes: 2
Views: 1201
Reputation: 172924
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);
Upvotes: 6