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
/* ... */
}
编译器需要先查看泛型声明才能声明特化,因此只需更改声明的顺序即可。
我有一个反序列化函数。使用模板,我希望能够得到我正在反序列化的东西。换句话说,我想要一个计算序列化事物的函数和另一个处理反序列化的函数。如果我以不同的方式命名它们,我没有问题,而且,事实上,这是一个非常简单的解决方案,我肯定会这样做。但令我困扰的是,我不明白为什么不能接受以下内容。
#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
/* ... */
}
编译器需要先查看泛型声明才能声明特化,因此只需更改声明的顺序即可。