当前位置: 首页 > 知识库问答 >
问题:

为什么这不是函数模板的部分专门化?

丁震博
2023-03-14

让我们考虑以下代码:

template<typename T>
void func(T);
template<typename T>
void func(T*); // an overload

我知道第二个声明是重载,而不是部分专业化:

template<typename T>
void func<T*>(T*); // not allowed by C++ standard

但我想知道它与部分专业化有何不同?它为我们提供了与部分专业化相同的功能,不是吗?

共有1个答案

陆绪
2023-03-14

但我想知道它与部分专业化有何不同?

不同之处在于它不是一种专门化。模板专门化是主模板的替代实现,在提供某些模板参数时使用。当您将一组参数应用于代码中的模板名称时,这将导致编译器调用模板实例化机制。其中一部分是检查主模板的显式专门化,如果它们与这些参数匹配,则使用它们。

对于函数重载,这不会发生。而是使用过载解析机械。

实现相同目的的不同手段。

如果您需要详细信息,函数不仅仅是一个名称;这是一个名字和它的签名。因此,具有相同名称但不同签名的函数是不同的函数。因此,该行不声明同一模板函数的专门化;它声明了一个新的主模板。

它给我们提供了与局部特化相同的功能,不是吗?

在某些情况下,部分专业化可能比重载更方便,但这些可能基于SFINAE或其他元编程技巧。是的,部分专业化可以完成重载的大部分工作。

但不管函数部分专门化是否存在,您仍然需要重载规则。对于非模板情况和可以用非模板版本重载模板函数的情况,需要这些规则。或者具有比主模板更多或更少的参数。您需要能够有一些构造函数,它们是模板,而有些不是。

因此,无论如何,都将有关于重载如何与模板函数一起工作的规则。

因此,更好的说法是,函数重载在很大程度上使函数部分专门化变得多余(这可能是它不存在的原因)。或者更好的是,类模板部分专门化是一种赋予类模板类似于函数重载特性的方法。

 类似资料:
  • 如果我有一些琐碎的东西,比如(为了澄清,我并不是说这是一个好的实现,只是一个演示成员函数部分模板专门化失败的示例): 我无法通过执行以下操作来专门化每个功能: 不幸的是,C标准不允许: 14.5.5.31、类模板局部特化成员的模板参数列表应与类模板局部特化的模板参数列表匹配类模板局部特化成员的模板参数列表应与类模板局部特化的模板参数列表匹配。 因此,唯一的解决方案(据我所知)是使用类型特征或用样板

  • 这个问题可能太难在标题中的on句子中描述,但这里有一个最小的例子: 当两种类型相同时 当这两种类型是同一类型的类模板的实例化时 天真地说,我们希望第二个部分专门化不会与第一个不明确,因为它感觉“更专门化”,对基础模板上和的推导类型施加更多限制。然而,主要的编译器似乎同意我们的期望是错误的:为什么它不被认为是更专业化的?

  • 我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误

  • 在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。

  • 我试图编写一个可变函数模板来计算的字节大小。这将用于一个网络编程项目,我正在工作。第一步,我在没有工作的variadic模板的情况下想出了这个: 错误代码#2。如果我将variadic模板放在不同的位置: 我得到了 错误:重载的'size t ()'调用不明确