【问题标题】:Priority between normal function and Template function普通功能和模板功能之间的优先级
【发布时间】:2012-04-24 03:35:39
【问题描述】:

在以下代码中,主函数使用普通函数而不是模板函数。

#include <iostream>

using namespace std;

template <class T>
void num(T t){cout<<"T : "<<t;}

void num(int a){cout<<"wT : "<<a;}


int main()
{
    num(5);
    return 0;
}

这背后的可能原因是什么?

【问题讨论】:

标签: c++ templates overloading


【解决方案1】:

看看Herb Sutter的优秀文章"Why not specialize function templates?"

引用:

“最后,我们只关注函数模板,考虑重载规则,看看在不同情况下调用了哪些。规则很简单,至少在高层次上,可以表示为经典的二类系统:

  1. 非模板函数是一等公民。将选择与参数类型以及任何函数模板相匹配的普通旧非模板函数,而不是其他情况相同的函数模板。

  2. 如果没有至少一样好的一等公民可供选择,那么接下来参考函数基础模板作为二等公民。选择哪个函数基模板取决于哪个匹配最好并且是“最专业的”(重要说明:奇怪的是,“专业”的这种使用与模板专业化无关;这只是一种不幸的口语)根据一组公平神秘的规则:

    • 如果很明显有一个“最专业”的函数基础模板,那么就会使用那个。如果该基本模板恰好专门用于正在使用的类型,则将使用该专门化,否则将使用使用正确类型实例化的基本模板。

    • 否则,如果“最专业”的函数基模板存在相同的情况,则调用会产生歧义,因为编译器无法确定哪个更匹配。程序员必须做一些事情来限定调用并说出需要哪个调用。

    • 否则,如果没有可匹配的函数基模板,则调用错误,程序员将不得不修复代码。”

在您的代码示例中,正如 David Z. 所指出的,非模板函数 void num(int a) 将被选中,因为它在第一条规则中匹配。任何额外的函数模板只有在它们更匹配时才会被考虑

【讨论】:

    【解决方案2】:

    在这种情况下要调用模板方法,您需要使用num&lt;int&gt;(5) 而不是num(5) 显式调用该方法。尽管编译器可以推断,但非泛型方法优于泛型方法。您可以在此处查看此行为http://ideone.com/ccDJP

    【讨论】:

    • 谢谢。我想听听这句话“虽然编译器可以推断,但它会更喜欢非泛型方法而不是泛型方法”。
    • 是的,如果您考虑一下,使用非泛型会导致在文本中创建一个新的模板方法(C++ 模板本质上为使用的每种不同类型复制该方法)。如果已经有了,为什么还要努力:)
    • 另一种调用模板变体num&lt;&gt;(5);的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 2011-06-13
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多