函数模板显式特化声明中尾随模板参数的推导(无函数参数推导)

2024-04-12

(这个问题是评论中讨论的分支变量模板的模板特化和类型推导 https://stackoverflow.com/questions/61384251/template-specialization-of-variable-template-and-type-deduction.)


[温度解释规格]/10 https://timsong-cpp.github.io/cppwp/n4659/temp.expl.spec#10指出[emphasis mine]:

尾随一个模板参数 https://timsong-cpp.github.io/cppwp/n4659/temp.names#nt:template-argument 可以不指定 in the 模板 ID https://timsong-cpp.github.io/cppwp/n4659/temp.names#nt:template-id命名显式函数模板特化前提是可以 从函数参数类型推导出来。 [ 例子:

template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v);

// explicit specialization for sort(Array<int>&)
// with deduced template-argument of type int
template<> void sort(Array<int>&);

—《示例结束》]

这显然适用于(完全)显式专业化foo(T)在下面的例子中:

#include <iostream>

template <typename T>
void foo(T) { std::cout << "primary\n"; }

template <>
void foo(int) { std::cout << "int\n"; }
// OK   ^<int> deduced from template argument deduction
//             in this _declaration_, as of [temp.expl.spec]/10

int main()
{
    const int a = 42;
    foo(a);  // int
    // OK, <int> deduced from template argument deduction.
}

然而,对于 clang 和 GCC,对于我测试过的所有各种 ISO C++ 版本,这也适用于函数模板中没有函数参数的示例,并且其类型模板参数仅作为函数模板的返回类型:

#include <iostream>

template <typename T>
T bar() { std::cout << "primary\n"; return 0; }

template <>
int bar() { std::cout << "int\n"; return 42; }
//     ^<int> deduced?

int main()
{
    (void)bar<int>();  // int
    //        ^^^ OK, no template argument deduction.
}

我对这个术语有点困惑“推论”在上面的引用中,afaics 并不是指典型(调用站点/实例化)模板参数推导意义上的推导,而是指专门化声明上下文中的推导。

问题:

  • ISO C++ 标准中的哪些内容涵盖了尾随模板参数在显式函数模板特化的声明中,模板参数仅作为返回类型出现,实际上可以省略(推导)吗?

我认为 [temp.expl.spec]/10 在说“函数参数类型”而不仅仅是“函数类型”时有不好的措辞,这实际上是在模板参数推导中用于函数模板的显式特化的。 (当然,函数参数类型可能不止一种。)

不同的上下文指定不同的依赖类型集(P)和指定的(通常是非依赖的)类型(A) 用于模板参数推导,如小节中列出的[临时扣费电话] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct#call, [temp.deduct.funcaddr] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct#funcaddr, [温度扣除转换] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct#conv, [温度扣除部分] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct#partial, and [温度扣除.decl] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct#decl.

最熟悉的案例可能是第一个,[临时扣费电话] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct#call:调用函数模板时,函数参数类型为P参数表达式的类型是A,但函数模板的返回类型不参与。

其中最后一个,[温度扣除.decl] https://timsong-cpp.github.io/cppwp/n4659/temp.deduct#decl,涵盖了函数模板的显式特化的匹配(如您的示例中所示)、函数模板的显式实例化以及支持函数模板的特定特化的友元声明。对于这些情况,整个函数类型是P and A。由于函数类型被视为由返回类型和参数类型形成的“复合类型”,类似于指针类型T*由类型形成T,这允许推断出现在返回类型和/或参数类型中的模板参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数模板显式特化声明中尾随模板参数的推导(无函数参数推导) 的相关文章

  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • C 中的位移位

    如果与有符号整数对应的位模式右移 则 1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is impleme
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 将变量分配给另一个变量,并将一个变量的更改反映到另一个变量中

    是否可以将一个变量分配给另一个变量 并且当您更改第二个变量时 更改会瀑布式下降到第一个变量 像这样 int a 0 int b a b 1 现在 b 和 a 都 1 我问这个问题的原因是因为我有 4 个要跟踪的对象 并且我使用名为 curr
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co

随机推荐