简体   繁体   English

将调用两个重载模板中的哪个?

[英]Which of two overloaded templates will be called?

I am still trying to figure out templates. 我仍在尝试找出模板。 I have read about the specialization rules and don't understand what is happening here. 我已阅读有关专业化规则的信息,但不了解这里发生的情况。

I have defined the following in templates.h: 我在template.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;
}

Now if I include this and call it in my main like this 现在,如果我包括这个,并像这样在我的主体中调用它

  f(1);
  f("x");

I get 我懂了

one
one

Now the questions is, why is the first more specific than the second for ints? 现在的问题是,对于整数,为什么第一个比第二个更具体? I feel like it should at least be ambiguous and not work at all. 我觉得它至少应该是模棱两可的并且根本不起作用。

First off, you don't have specializations, but two separate, unrelated overloads . 首先,您没有专长,但是有两个独立的,不相关的重载

Secondly, the second overload is trivially non-viable, since you call the function without template arguments, and thus there is no way to deduce the template parameter bar . 其次,第二个重载是不可行的,因为您调用的函数没有模板参数,因此无法推断模板参数bar So only the first overload is viable, and gets used. 因此,只有第一个重载是可行的,并得到使用。


An actual specialization would look like this: 实际的专业化如下所示:

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

Better yet, stick with overloads (it's generally better to overload functions than to provide template specializations), but make the second one a non-template: 更好的是,坚持使用重载(重载函数通常比提供模板专业化更好),但是将第二个非模板:

void f(int p) { /* ... */ }

The second overload one has no template dependency on function arguments, so you would have to call it like this: 第二个重载没有对函数参数的模板依赖性,因此您必须像这样调用它:

f<std::string>(1);
f<double>(42);
f<SomeType>(1);

Whether it makes sense to have the second version is a different matter. 使用第二个版本是否有意义是另一回事。 You could imagine having a template parameter that does have some effect on the internal logic of the function: 您可以想象有一个模板参数确实会对函数的内部逻辑产生影响:

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);

On the other hand, your SomeType could be a function parameter: 另一方面,您的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);

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

f<whatever>(1);

The one, which prints "two" is not recognized as explicit specialization. 印有“两个”的那个未被识别为显式专业化。 Try thisL 试试这个

template <>
void f(int p)
{
  std::cout << "two" << std::endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM