我仍在尝试找出模板。我已经阅读了有关专业化规则的内容,并且不明白这里发生了什么。
我在templates.h中定义了以下内容:
#include <iostream>
template <typename foo>
void f(foo p)
{
std::cout << "one" << std::endl;
}
template <typename bar>
void f(int p)
{
std::cout << "two" << std::endl;
}
现在,如果我包含这个并在我的主要中像这样调用它
f(1);
f("x");
我得到了
one
one
现在的问题是,为什么第一个比第二个更具体是针对整数?我觉得它至少应该是模棱两可的,根本不起作用。
答案 0 :(得分:5)
首先,您没有专业化,而是两个独立的,无关的重载。
其次,第二个重载通常是不可行的,因为您在没有模板参数的情况下调用该函数,因此无法推导出模板参数bar
。因此,只有第一次过载是可行的,并且可以使用。
实际的专业化将如下所示:
template <>
void f<int>(int p) { /* ... */ }
更好的是,坚持使用重载(通常更好地重载函数而不是提供模板特化),但是将第二个作为非模板:
void f(int p) { /* ... */ }
答案 1 :(得分:4)
第二个重载没有模板对函数参数的依赖,所以你必须这样调用它:
f<std::string>(1);
f<double>(42);
f<SomeType>(1);
拥有第二个版本是否有意义是另一回事。你可以想象有一个做的模板参数对函数的内部逻辑有一些影响:
template <typename SomeType>
int foo(int seed) {
// instantiate a SomeType and use it to calculate return value
};
int i = foo<Type1>(42);
int j = foo<Type2>(42);
另一方面,您的SomeType
可能是一个函数参数:
template <typename SomeType>
int foo(int seed, const SomeType& s) {
// use s to calculate return value
};
Type1 t1;
Type2 t2;
int i = foo(42, t1);
int j = foo(42, t2);
答案 2 :(得分:1)
在第二个bar
中无法从函数参数中推导出来,并且必须明确给出:
f<whatever>(1);
答案 3 :(得分:0)
打印&#34;两个&#34;不被认为是明确的专业化。试试这个
template <>
void f(int p)
{
std::cout << "two" << std::endl;
}