函数的模板专用化和重载之间的区别? [英] Differences between template specialization and overloading for functions?

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

问题描述

所以,我知道这两个代码之间有一个区别:

So, I know that there is a difference between these two tidbits of code:

template <typename T>
T inc(const T& t)
{
    return t + 1;
}

template <>
int inc(const int& t)
{
    return t + 1;
}

template <typename T>
T inc(const T& t)
{
    return t + 1;
}

int inc(const int& t)
{
    return t + 1;
}

我很困惑这两者之间的功能差异。

I am confused as to what the functional differences between these two are. Can someone show some situations where these snippits act differently from each other?

推荐答案

我只能想到几个区别 - 这里是一些例子,不一定造成伤害(我想)。我省略了定义以保持简洁

I can only think of a few differences - here are some examples that don't necessarily cause harm (i think). I'm omitting definitions to keep it terse

template <typename T> T inc(const T& t);
namespace G { using ::inc; }
template <> int inc(const int& t);
namespace G { void f() { G::inc(10); } } // uses explicit specialization

// --- against ---

template <typename T> T inc(const T& t);
namespace G { using ::inc; }
int inc(const int& t);
namespace G { void f() { G::inc(10); } } // uses template

这是因为通过名称查找找不到特殊化, ,所以使用声明会自动考虑以后引入的特化。

That is because specializations are not found by name lookup, but by argument matching, so a using declaration will automatically consider a later introduced specialization.

然后,您当然不能部分地专门化功能模板。然而,重载通过部分排序(使用不同的类型,现在,为了我的观点)实现了非常相似的东西。

Then, you of course cannot partially specialize function templates. Overloading however accomplishes something very similar by partial ordering (using different types now, to make my point)

template <typename T> void f(T t); // called for non-pointers
template <typename T> void f(T *t); // called for pointers.

int a;
void e() {
  f(a); // calls the non-pointer version
  f(&a); // calls the pointer version
}

专业化。另一个例子是当涉及引用时,引起模板参数推导以寻找所涉及类型(模基/导出类关系和常量)的精确匹配:

That wouldn't be possible with function template explicit specialization. Another example is when references are involved, which causes template argument deduction to look for an exact match of the types involved (modulo base/derived class relationships and constness):

template<typename T> void f(T const &);
template<> void f(int * const &);

template<typename T> void g(T const &);
void g(int * const &);

int a[5];
void e() {
  // calls the primary template, not the explicit specialization
  // because `T` is `int[5]`, not `int *`
  f(a);

  // calls the function, not the template, because the function is an
  // exact match too (pointer conversion isn't costly enough), and it's 
  // preferred. 
  g(a);
}






使用重载,因为它更丰富(允许类似部分专门化的东西允许),此外,你可以将函数放在任何你想要的命名空间(尽管它不会严格超载)。例如,不必专门化 std :: 命名空间中的 std :: swap ,您可以将 swap 重载在自己的命名空间,并使其可调用由ADL。


I recommend you to always use overloading, because it's richer (allows something like partial specialization would allow), and in addition you can place function in whatever namespace you want (although then it's not strictly overloading anymore). For example, instead of having to specialize std::swap in the std:: namespace, you can place your swap overload in your own namespace and make it callable by ADL.

无论你做什么,从不混合专业化和重载,这将是一个混乱,如本文指出。该标准有一个可爱的段落

Whatever you do, never mix specialization and overloading, it will be a hell of a mess like this article points out. The Standard has a lovely paragraph about it


为函数模板,类模板,类模板的成员函数,静态类模板的数据成员,类模板的成员类,类模板的成员类模板,类模板的成员函数模板,类模板的成员模板的成员函数,非模板类的成员模板的成员函数,成员函数模板类模板的成员类等,以及类模板的部分专业化声明,非模板类的成员类模板,类模板的成员类模板等的放置可以影响程序是否根据显式专用化声明和它们的实例化点在翻译单元中的相对定位,如上下文所述。当写专业化时,要小心它的位置;或使它编译将是一个试验,以点燃其自焚。

The placement of explicit specialization declarations for function templates, class templates, member functions of class templates, static data members of class templates, member classes of class templates, member class templates of class templates, member function templates of class templates, member functions of member templates of class templates, member functions of member templates of non-template classes, member function templates of member classes of class templates, etc., and the placement of partial specialization declarations of class templates, member class templates of non-template classes, member class templates of class templates, etc., can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.

这篇关于函数的模板专用化和重载之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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