试图在 C++ 中使用非类型参数专门化模板函数

attempting to specialize template function with non-type argument in C++

我有一个模板化函数,它将数组引用作为参数:

template<typename T, int arrSize>
void foo(T (&pArr)[arrSize]) {
    cout << "base template function" << endl;
}

我想专门为 C 字符串编写此函数:

template<const char *, int arrSize>
void foo(const char * (&pArr)[arrSize]) {
    cout << "specialized template function" << endl;
}

我尝试实例化基础和专业化:

int main(int argc, const char **argv) {
    float nums[] = {0.3, 0.2, 0.11};
    const char *words[] = {"word1", "word2"};
    foo(nums);
    foo(words);
}

但我似乎只得到了基础实例化:

./foo
base template function
base template function

我在 Mac 上使用 clang++ 和 -std=c++17 编译了这个。

尝试:

template<int arrSize>
void foo(const char * (&pArr)[arrSize]);

您正在定义一个需要 non-deducible char const* non-type 参数的重载。

问题是您提供的第二个重载函数模板有一个non-type类型的模板参数const char* 无法从函数参数推导出来。因此,要调用这个重载版本,我们必须显式提供与此 non-type 参数对应的模板参数。

解决,只需删除第一个 non-type 模板参数,如图 below:

template<typename T, int arrSize>
void foo(T (&pArr)[arrSize]) {
    std::cout << "base template function" << std::endl;
}
//overload for C-strings
template< int arrSize>
void foo(const char (&pArr)[arrSize]) {
    std::cout << "single C-string overloaded version" << std::endl;
}
//overload for array of pointers to C-strings
template<std::size_t arrSize>
void foo(const char*(&pArr)[arrSize])
{
    std::cout<<" array of pointers to C-string version"<<std::endl;
}
int main(int argc, const char **argv) {
    float nums[] = {0.3, 0.2, 0.11};
    const char words[] = {"word1"};
    const char* wordPtrs[] = {"word1", "word2"};
    
    foo(nums); //calls base
    foo(words);//calls single C-string version
    foo(wordPtrs);//calls array of pointers to C-string version
}

Demo

另请注意,函数模板不能部分特化,但可以完全特化或重载。