3

我仍在尝试找出模板。我已阅读有关专业化规则的信息,但不明白这里发生了什么。

我在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

现在的问题是,为什么第一个比第二个更具体?我觉得它至少应该是模棱两可的,根本不起作用。

4

4 回答 4

5

首先,您没有专业化,而是两个独立的、不相关的重载

其次,第二个重载非常不可行,因为您在没有模板参数的情况下调用函数,因此无法推断模板参数bar。所以只有第一个重载是可行的,并被使用。


实际的专业化看起来像这样:

template <>
void f<int>(int p) { /* ... */ }

更好的是,坚持重载(重载函数通常比提供模板特化更好),但将第二个设为非模板:

void f(int p) { /* ... */ }
于 2012-08-01T08:39:53.837 回答
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);
于 2012-08-01T08:36:31.530 回答
1

在第二个bar中,不能从函数参数中推导出来,必须明确给出:

f<whatever>(1);
于 2012-08-01T08:37:21.903 回答
0

打印“二”的那个不被认为是明确的专业化。试试这个L

template <>
void f(int p)
{
  std::cout << "two" << std::endl;
}
于 2012-08-01T08:42:16.973 回答