首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++模板选择

C++模板选择
EN

Stack Overflow用户
提问于 2013-03-19 18:31:31
回答 1查看 1.6K关注 0票数 12

给定以下代码:

代码语言:javascript
复制
#include <memory>
#include <iostream>

using namespace std;

template<typename T>
void test(T & value) {
  cout << "most generic" << endl;
}

template<typename T>
void test(shared_ptr<T> & value) {
  cout << "shared_ptr" << endl;
}

class A {};

int main(int argc, char ** argv) {
  A a;
  shared_ptr<A> p(new A());
  test(a);
  test(p);
  return 0;
}

为什么呼叫是

代码语言:javascript
复制
test(p)

使用T=A实例化第二种形式的测试,而不是抱怨它无法区分两个签名?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-19 18:32:40

因为即使它们都是重载解析的可行选择,第二个函数模板比第一个更加专门化。

根据C++11标准的13.3.3/1段:

...给定这些定义,如果对于所有自变量i,( F1 )不是比ICSi( F2 )差的转换序列,则可行函数F2被定义为比另一可行函数ICSi更好的函数,然后

-对于某些参数j,ICSj(F1)是比ICSj(F2)更好的转换序列,或者,如果不是这样,

-上下文是通过用户自定义转换进行的初始化(参见8.5、13.3.1.5和13.3.1.6),从F1的返回类型到目标类型(即被初始化的实体的类型)的标准转换序列是比从F2的返回类型到目标类型的标准转换序列更好的转换序列。..。或者,如果不是这样,

- F1是一个非模板函数,而F2是一个函数模板专门化,如果不是这样,

- F1和F2是函数模板的特殊化,根据14.5.6.2中描述的偏序规则, F1的函数模板比F2的模板更加专业化。

§14.5.6.2然后说明如何确定函数模板比另一个函数模板更加专门化。特别是,根据14.5.6.2/2:

偏序通过依次转换每个模板(参见下一段)并使用函数类型执行模板参数推导,来选择两个函数模板中哪个比另一个更专业。扣减处理确定其中一个模板是否比另一个模板更专业。如果是这样,则部分排序过程选择的模板是更专业的模板。

标准中的正式定义可能很难破译,但它们的复杂性通常是为了明确地使语言表现得像我们在大多数情况下自然期望的那样。

我们对您提供的重载的直观期望是,当参数类型为std::shared_ptr<int>时,应该选择接受std::shared_ptr<T>的重载,因为它似乎专门处理std::shared_ptr<>对象,因此,它看起来比无约束重载更好(更专业)。

将这种直观的期望转换为一组明确的规则的正式过程听起来可能很复杂,但在我们的情况下,遵循它并不是特别困难,我们想要确定这种过载:

代码语言:javascript
复制
template<typename T>
void f(std::shared_ptr<T>);

比这更专业:

代码语言:javascript
复制
template<typename U>
void f(U);

虽然在这种情况下,我们很容易根据我们的直觉来区分哪个更专业,但编译器必须依赖于一个算法,并且这个算法必须在所有情况下都能工作。

在这种情况下,该机制如下所示:

  1. 接受第一个重载,用它的模板参数T替换类型参数(任何类型参数),例如int,并实例化相应的签名-函数参数的类型总是可以通过提供该类型的对象(本例中为shared_ptr<int>)作为其输入来调用第二个重载,并从中推导出类型U
  2. 好的,答案是是<代码>E227。从另一方面来说,U将被推断为std::shared_ptr<int>;
  3. The :拿第二个重载,用它的模板参数U代替任何类型的参数,例如bool,并实例化相应的签名-函数参数的类型将是bool;
  4. Is。通过提供该类型的对象(bool)作为参数,并从中推导出类型T,总是可以调用第一个重载。
  5. 这里的答案当然是No。无法推导出与bool;
  6. Conclusion:匹配的T,因为第一个重载比second.

更专业

当然,当有多个模板参数和多个函数参数时,事情会变得稍微复杂一些,但机制基本相同。

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15497004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档