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

C++ template specialisation, but no match found

我有一个反序列化函数。使用模板,我希望能够得到我正在反序列化的东西。换句话说,我想要一个计算序列化事物的函数和另一个处理反序列化的函数。如果我以不同的方式命名它们,我没有问题,而且,事实上,这是一个非常简单的解决方案,我肯定会这样做。但令我困扰的是,我不明白为什么不能接受以下内容。

#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),但我认为可以推断出专业化。

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

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

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

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

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

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