2 qq 21044655 qq_21044655 于 2015.06.06 23:04 提问

c++重载决议具体化优先于函数模板
c++

template void f(T a){ cout << "aaaaaaa"; }
template <> void f(int & a){ cout << "fffffffffff"; }
int b;f(b);
为什么输出aaaaaaa,不是应该输出fffffffffff吗,看书上说具体化优先于模板函数的

求知道的大神指点下啦,万分感谢

5个回答

devmiao
devmiao   Ds   Rxr 2015.06.06 23:23
 #include <iostream>
using namespace std;
template <typename T>void f(T a){ cout << "aaaaaaa"; }
void f(int & a){ cout << "fffffffffff"; }
int main()
{
 int b;
 f(b);
}

http://codepad.org/iyORv2CE
在线运行的结果
输出的是fffffffffff

devmiao
devmiao   Ds   Rxr 2015.06.07 00:22

如果你这么写

# include <iostream>
using namespace std;

template <> void f(int &a){ cout << "fffffffffff"; }

int main()
{
    int bb=9;
    f(bb);

    return 0;
} 

根本认不到f
说明不是重载选择的问题,而是后面那个函数根本不合法。

devmiao
devmiao 回复qq_21044655: 看我的代码,认不到f的
大约 3 年之前 回复
qq_21044655
qq_21044655 http://codepad.org/PNFbR2Hc
大约 3 年之前 回复
nswcfd
nswcfd   2015.06.09 10:49

很奇怪,在g++上的结果确实的第一个,即来自函数模版,而非其特例。

ps,如果把特例的参数,从int &修改为int(去掉引用),行为就正常了。

看起来,模版推导的逻辑,对引用有什么特别的规则?

nswcfd
nswcfd   2015.06.09 11:28

http://stackoverflow.com/questions/4677592/specializing-function-template-for-reference-types
如果一定要int&版本的命中,不要使用模版,而使用overload机制。

nswcfd
nswcfd   2015.06.09 11:39

感觉函数模版的推导逻辑是,先在多个模版之间选择最合适的模版,然后看最合适的模版有没有特化。就这个例子而言,由于只有一个模版,那么根据f(bb)得到T=int,而第二个是针对int&的特化,两者不匹配。

nswcfd
nswcfd PS,stackoverflow上有人回答,A reference is just an alias, not a type. So when you call f(z), it matches the first version with T=int, which is a better option that T=int&。
大约 3 年之前 回复
nswcfd
nswcfd 模块的推导(Template argument deduction)的规则挺复杂的,http://en.cppreference.com/w/cpp/language/function_template有一段描述。
大约 3 年之前 回复
qq_21044655
qq_21044655 当type传给type &时,是无关紧要的转换,这是与type传给tpye完全匹配的。type表任意类型。书上看的
大约 3 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
为什么我们不建议使用函数模板具体化
你有过使用了函数具体化模板却没有得到预期结果的经历吗? 本文部分译自[Why Not Specialize Function Templates?]。具有一定英语阅读能力的读者强烈和强烈建议跳过此博客直接阅读原文。(http://www.gotw.ca/publications/mill17.htm#1)
C++函数模板的具体化和实例化
原文连接:http://hi.baidu.com/sucjhwaxp/blog/item/f0ee4e1145ca83e7c2ce793e.html C++函数模板----模板实例化、具体化 函数模板是C++新增的一种性质,它允许只定义一次函数的实现,即可使用不同类型的参数来调用该函数。这样可以减小代码的书写复杂度,同时也便于修改。 mark:使用函数模板并不会减少最终可执行程序的大小,
函数模板和类模板的实例化和具体化
一.函数模板 1.显示实例化(explicit instantiation)和显示具体化(explicit specialization)的区别: (1) 形式上: 显示实例化:  template  void  Swap (int ,int); 显示具体化:  template (int,int);              或     template 从
C++ 函数模板 实例化和具体化
函数模板是C++新增的一种性质,它允许只定义一次函数的实现,即可使用不同类型的参数来调用该函数。这样做可以减小代码的书写的复杂度,同时也便于修改。但是,在代码中包含函数模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。编译器使用模板为特定类型生成函数定义时,得到的是模板实例(instantiation)。 1 实例化 实例化有两种形式,分别为显式实例化和隐式实例化。模板并非函数定义
关于函数模板以及具体化
#include #include using namespace std; template T maxn(T arr[],int n); template <> const char*maxn(const char *arr[],int n); int main() { int arr1[6]={1,2,3,4,5,6}; cout<<m
c++重载与模板
一、 模板是泛型编程的重要支持,函数和类模板在STL中运用的非常广泛,首先谈谈c中的函数重载和c++中的函数模板的区别: 1、首先,函数重载是函数名相同,但参数个数和类别不同,如果增加参数个数和参数型别就要重新编写相应的重载函数,而相对于函数模板就比较灵活,我们只要编写一个函数模板,编译器在编译是就会根据参数类型特例化出相应的版本,而且模板支持可变参数(template,..代表0个或多个参数)
C++模板,模板具体化,特例化
1.模板重载原则函数同名(重载)时,调用优先级通常为:普通函数 >显式具体化(template specilazation)>显式实例化>一般模版函数 但更一般而言,有两条规则: 1>如果各自函数形参和调用处的实参 并非精确匹配,则会优先选择不需要转换的; 比如 void func(string str); template void func(T*); ….func(“abcd”);
C++ 重载决议overload resolution 与 SFINAE
提供一个约束版本和一个任意参数版本,在约束版本不能替换成功时,还有任意参数版本可以替换成功。所有可能的函数模板构成一个候选集,从候选集中挑选一个,决胜者得到最终的匹配。 只有在编译器选中主函数模板时,全特化版本才可能被使用。任意参数版本只有当所有候选版本都不能替换成功时,才会匹配。
c++模板显示实例化,显示具体化,隐式实例化
函数模板是C++新增的一种性质,它允许只定义一次函数的实现,即可使用不同类型的参数来调用该函数。这样做可以减小代码的书写的复杂度,同时也便于修改(注:使用模板函数并不会减少最终可执行程序的大小,因为在调用模板函数时,编译器都根据调用时的参数类型进行了相应实例化)。下面来看看函数模板的使用过程: [cpp] view plain copy struct j
函数模板的具体化有什么意义。
比如,你定义了一个函数模板template&amp;lt;typename T&amp;gt;void func(const T&amp;amp; t){ dosomething(t);}但是,当T是整数的时候你不想dosomething,而是想killsomeone,那就需要具体化了。具体化有2种形式,一种是显式具体化即定义一个特殊类型的实现template&amp;lt;&amp;gt;void func&amp;lt;int&amp;gt;...