功能模板重载

sky*_*oor 22 c++ templates overloading

任何人都可以总结一下函数模板重载的想法吗?重要的是,模板参数或功能参数?返回值怎么样?

例如,给定一个功能模板

template<typename X, typename Y> void func(X x, Y y) {}
Run Code Online (Sandbox Code Playgroud)

什么是重载的功能模板?

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) {}
Run Code Online (Sandbox Code Playgroud)

vis*_*tor 30

在该列表中,只有第二个引入歧义,因为函数 - 无论它们是否是模板 - 都不能基于返回类型重载.

你可以使用其他两个:

template<typename X> void func(X x, int y);
Run Code Online (Sandbox Code Playgroud)

如果调用的第二个参数是int,则将使用,例如 func("string", 10);

template<class X, class Y, class Z> void func(X x, Y y, Z z);
Run Code Online (Sandbox Code Playgroud)

如果你用三个参数调用func,将使用它.


我不明白为什么其他一些答案提到模板函数和函数重载不混合.他们肯定会这样做,并且有一些特殊的规则如何选择调用函数.

14.5.5

功能模板可以使用其他功能模板和普通(非模板)功能重载.普通函数与函数模板无关(即,它永远不会被认为是特化),即使它与可能生成的函数模板特化具有相同的名称和类型.)

非模板化(或"模板化程度较低")过载优于模板,例如

template <class T> void foo(T);
void foo(int);

foo(10); //calls void foo(int)
foo(10u); //calls void foo(T) with T = unsigned
Run Code Online (Sandbox Code Playgroud)

您的第一个带有一个非模板参数的重载也属于此规则.

如果在几个模板之间进行选择,则首选更专业的匹配:

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
Run Code Online (Sandbox Code Playgroud)

您可以在标准的同一章(功能模板)中找到所有规则的更正式的描述


最后,在某些情况下,两个或多个重载将是不明确的:

template <class T> void foo(T, int);
template <class T> void foo(int, T);

foo(1, 2);
Run Code Online (Sandbox Code Playgroud)

这里的呼吁是模棱两可的,因为两个候选人都是同样专业的.

您可以使用(例如)消除这种情况的歧义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); //calls the first
Run Code Online (Sandbox Code Playgroud)

这里,库在第二个重载的返回类型中产生"替换失败",如果T = int,则从过载候选集中删除它.

在实践中,你应该很少遇到这样的情况.