函数模板重载 [英] function template overloading
问题描述
有人可以总结函数模板重载的想法吗?重要的是,模板参数还是函数参数?例如,给定一个函数模板
<$ c $ c> template< typename X,typename Y> void func(X x,Y y){};
什么是重载的函数模板?
1)template< typename X> void func(X x,int y){};
2)template< typename X,typename Y> X func(X x,Y y){};
3)template< class X,class Y,class Z> void func(X x,Y y,Z z){};
只有第二个引入歧义,
您可以使用其他两个:
模板< typename X> void func(X x,int y);如果调用的第二个参数是一个int,将使用
,例如 func(string,10);
template< class X,class Y,class Z> ; void func(X x,Y y,Z z);如果您使用三个参数调用func,将使用
。
我不明白为什么一些其他答案提到模板函数和函数重载不混合。他们当然会做,并且有特殊的规则如何选择调用的函数。
14.5.5
可以
重载与其他函数
模板和正常
(非模板)函数。正常的
函数与
函数模板无关(即,从不认为
是专业化),即使
具有相同的名称和类型
也是如此
作为潜在生成的函数
模板专用化。)
非模板是模板,例如
template< class T> void foo(T);
void foo(int);
foo(10); // calls void foo(int)
foo(10u); //调用void foo(T)with T = unsigned
您的第一个重载与一个非模板参数
在多个模板之间进行选择时,首选更专业的匹配:
template< class T> void foo(T);
template< class T> void foo(T *);
int i;
int * p;
int arr [10];
foo(i); //调用第一个
foo(p); // calls second
foo(arr); // calls second:array decays to pointer
你可以找到所有规则的更正式的描述标准的同一章(功能模板)
两个或多个重载将是不明确的:
template< class T> void foo(T,int);
template< class T> void foo(int,T)
foo(1,2);
这里的调用是不明确的,因为两个候选人同样是专门的。
您可以使用(例如) boost :: disable_if
来消除这种情况的歧义。例如,我们可以指定当T = int时,第二个重载不应该作为重载候选包括:
#include< boost / utility / enable_if.hpp>
#include< boost / type_traits / is_same.hpp>
template< class T>
void foo(T x,int i);
template< class T>
typename boost :: disable_if< boost :: is_same< int,T> > :: type
foo(int i,T x);
foo(1,2); //调用第一个
这里库在第二个返回类型中产生一个替换失败
在实践中,你应该很少遇到这种情况。
Can anybody summarize the idea of function template overloading? What matters, template parameter or function parameter? What about the return value?
For example, given a function template
template<typename X, typename Y> void func(X x, Y y) {};
what's the overloaded function template?
1) template<typename X> void func(X x, int y) {};
2) template<typename X, typename Y> X func(X x, Y y) {};
3) template<class X, class Y, class Z> void func(X x, Y y, Z z) {};
Of that list only the second introduces ambiguity, because functions - regardless of whether they are templates - can't be overloaded based on return type.
You can use the other two:
template<typename X> void func(X x, int y);
will be used if the second argument of the call is an int, e.g func("string", 10);
template<class X, class Y, class Z> void func(X x, Y y, Z z);
will be used if you call func with three arguments.
I don't understand why some other answers mentions that template functions and function overloading doesn't mix. They certainly do, and there are special rules how the function to call is selected.
14.5.5
A function template can be overloaded with other function templates and with normal (non-template) functions. A normal function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.)
A non-templated (or "less templated") overload is preferred to templates, e.g
template <class T> void foo(T);
void foo(int);
foo(10); //calls void foo(int)
foo(10u); //calls void foo(T) with T = unsigned
Your first overload with one non-template parameter also falls under this rule.
Given choice between several templates, more specialized matches are preferred:
template <class T> void foo(T);
template <class T> void foo(T*);
int i;
int* p;
int arr[10];
foo(i); //calls first
foo(p); //calls second
foo(arr); //calls second: array decays to pointer
You can find a more formal description of all the rules in the same chapter of the standard (Function templates)
And finally there are some situations where two or more overloads would be ambiguous:
template <class T> void foo(T, int);
template <class T> void foo(int, T);
foo(1, 2);
Here the call is ambiguous, because both candidates are equally specialized.
You can disambiguate such situations with the use of (for example) boost::disable_if
. For example, we can specify that when T = int, then the second overload shouldn't be included as an overload candidate:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
template <class T>
void foo(T x, int i);
template <class T>
typename boost::disable_if<boost::is_same<int, T> >::type
foo(int i, T x);
foo(1, 2); //calls the first
Here the library produces a "substitution failure" in the return type of the second overload, if T = int, removing it from the set of overload candidates.
In practice you should rarely run into situations like that.
这篇关于函数模板重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!