c – 如何确定函数专业化的主要模板?
函数模板专业化的主要模板通常非常直观,但是,我正在寻找正式的规则来理解更令人惊讶的情况.例如:
template <typename T,typename U> void f(T,U) {} // (1) template <typename T> void f(T,T) {} // (2) template <> void f(int,int) {} // (3); specializes (2),not (1); why? 从理论上讲,(3)也可以是(1)的特化,但实验表明它不是. 解决方法
让我们关注通用模板(1)和(2)的声明.
这是两个不同的模板,例如(2)不是(1)的专业化.好的,现在我们写专业时: template <> void foo(int,int) {} 在推断出要专门化的模板时,编译器将识别两个候选者.然后,它必须选择哪个最合适.这种选择的过程称为“partial ordering of function templates”.选择报价:
让我们调用S匹配模板集.然后,对于S中的每对(f1,f2),编译器将通过在其类型(resp.非类型)参数上应用虚拟类型(resp.值)来变换f1.然后它尝试将它与f2匹配.然后它通过转换f2并尝试将其与f1匹配来执行相同的过程.最后,在完成每一对之后,编译器可以确定哪个候选模板是最专业的.如果未能这样做,则编译失败. 在我们的例子中,我们有两个匹配的模板,因此我们应用上述过程: >转换(1)应用于(2):假设foo,T = T1且U = T2.它试图与(2)匹配:扣除失败 从这个过程,编译器推断出(2)比(1)更专业,你的专业化为(2).当编译器关注特定调用时,在重载解析期间应用相同的过程. 所有这些程序的一个例子如下(摘自@ Yakk的评论): template <typename T,U) { std::cout << "f(1)n"; } // f(1) template <typename T> void f(T,T) { std::cout << "f(2)n"; } // f(2) template <> void f(int,int) { std::cout << "f(3)n"; } // f(3); specializes f(2),not f(1); why? // Now the same specialization but without any template overload... template <typename T,typename U> void g(T,U) { std::cout << "g(1)n"; } // g(1) template <> void g(int,int) { std::cout << "g(3)n"; } // g(3); No ambiguity,specializes g(1) 接下来,让我们执行几个调用: f(1,1); // Prints f(3) f<int>(1,1); // Prints f(3) f<int,int>(1,1); // Prints f(1) g(1,1); // Prints g(3) g<int,1); // Prints g(3) 所有这些都可以在行动here – copied from @Yakk’s comment中看到. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |