函数模板重载 [英] function template overloading

查看:151
本文介绍了函数模板重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以总结函数模板重载的想法吗?重要的是,模板参数还是函数参数?例如,给定一个函数模板

 <$ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆