C++模板专业化,但未找到匹配项

C++ template specialisation, but no match found

本文关键字:专业化 C++      更新时间:2023-10-16

我有一个取消序列化函数。有了模板,我希望能够得到我正在取消序列化的东西。换句话说,我想要一个计算串行化的东西的函数和另一个处理去串行化的函数。如果我用不同的名字命名,我没有问题,事实上,这是一个非常容易的解决方案,我肯定会这么做。但令我困扰的是,我不明白为什么以下内容是不可接受的。

#include <string>
using std::string;
// In real life, fetch the stringified object.
template<>
string foo(int x);
// In real life, fetch an object and deserialize it.
template <typename T>
T foo(int x) {
    string s = foo<string>(x);
    T t;
    // Do something with s.
    return t;
}
template<>
string foo(int x) { return std::to_string(x); }

使用编译

clang -Wall -Wextra -std=c++14 foo.cc -o foo

表示

foo.cc:6:8: error: no function template matches function template specialization 'foo'
string foo(int x);

因此,显而易见的解决方案就是将第一个函数更改为string make_foo(int x)并使用它

为了帮助我学习,我一直在努力理解为什么我上面写的东西失败了。注意,我也尝试了template <> string foo<string>(int x),尽管我认为可以推断出专业化。

编译器需要先查看泛型声明,然后才能声明专门化,因此只需更改声明的顺序即可。

由于函数的返回类型不是函数声明的一部分,因此无法在此处推断特殊化。因此,如果没有函数参数类型依赖于模板参数,则必须编写完整的专业化:

template<>
std::string foo<std::string>(int x)
{
   /* ... */
}

例如,在以下情况下,您可以让编译器推断专业化:

template<class T>
void f(T arg)
{
    // generic case
    /* ... */
}
template<>
void f(bool arg)
{
    // bool case
    /* ... */
}