c++templatestemplate-specializationspecialization

Template method specialization for const char*


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.


Solution

  • 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);