c++templatesspecializationnon-type-template-parameter

Explicit Specialization of template function with non-type template argument list


I tried to explicitly specialize the following template function ArraySum for const char *:

template <typename T, int N>
T ArraySum (T (&pArr)[N])
{
    T sum = 0;
    for (T ele : pArr) {
        sum += ele;
    }
    return sum;
}

I have written the following specialization:

// Explicit Specialization of ArraySum for const char *
template<int N> const char * ArraySum <const char *> (const char * (&pArr)[N])
{
    std::string result = "";
    for (const char * str : pArr) {
        result += std::string(str);
    }
    char * c_result = new char [result.size() + 1];
    std::strcpy(c_result, result.c_str());
    return c_result;
}

When I compile the code, I get this error - error: template-id ‘ArraySum<const char*>’ in declaration of primary template template<int N> const char * ArraySum <const char *> (const char * (&pArr)[N]).

This error vanishes and the program compiles succesfully when I write template<int N> const char * ArraySum (const char * (&pArr)[N]) instead of template<int N> const char * ArraySum <const char *> (const char * (&pArr)[N]).

I know that writing <const char *> is optional. But why doesn't the program compile if I write that? And why removing <const char *> leads to successful compilation ?


Solution

  • You may not partially specialize a function.

    By removing the template argument const char * you declared a new overloaded template function with one non-type template parameter

    // Explicit Specialization of ArraySum for const char *
    template<int N> const char * ArraySum(const char * (&pArr)[N])
    {
        std::string result = "";
        for (const char * str : pArr) {
            result += std::string(str);
        }
        char * c_result = new char [result.size() + 1];
        std::strcpy(c_result, result.c_str());
        return c_result;
    }