C模板选择
给出以下代码:
#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; } 为什么是电话 test(p) 用T = A实例化第二种形式的测试,而不是抱怨它不能区分两个签名? 解决方法
因为即使它们都是可重复解决的可行选择,所以第二个功能模板比第一个更加专业化.
根据C11标准第13.3.3 / 1段:
§14.5.6.2然后说明如何确定功能模板比另一个功能模板更专业化.特别是,根据14.5.6.2/2:
标准中的正式定义可能非常难以破译,但是它们的复杂性通常意味着明确地使语言的行为与大多数情况下我们预期的一样. 我们可以提供的关于您提供的重载的直观预期是接受std :: shared_ptr< T>当参数的类型为std :: shared_ptr< int>,因为它似乎是处理std :: shared_ptr<>因此,它看起来像一个比无约束的超载更好(更专业化)的候选人. 将这种直观的期望转化为明确的规则集的正式程序可能听起来很复杂,但是在我们的情况下,并不特别困难,我们想确定这是否超载: template<typename T> void f(std::shared_ptr<T>); 比这更专业: template<typename U> void f(U); 尽管在这种情况下,我们很容易根据我们的直觉来判断哪一种更加专业化,但是编译器必须依赖于一种算法,而且该算法必须在所有情况下工作. 在这种情况下,机制将如下: >取第一个重载,将其模板参数T替换为类型参数(任何类型参数),例如int,并实例化相应的签名 – 函数参数将具有类型std :: shared_ptr< int>; 当然,当有多个模板参数和多个函数参数时,事情变得稍微复杂一点,但是机制几乎相同. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |