为什么接受数组的 C++ 模板并不比根据 GCC 5.3 和 Clang 4.0 接受指针的模板更专业?

2024-03-22

为什么接下来的两个模板声明不明确(因此两者都不比另一个更专业)?我知道这个问题在 Stack Overflow 上已经被多次提出,但通常人们会回答如何解决歧义,而不是回答为什么会发生这种情况。

I. template <class T> void func(char* buf, T size) {}

II. template <std::size_t N> void func(char (&buf)[N], std::size_t size) {}

尝试通过 C++14 标准的步骤来解决部分函数模板排序 (14.5.6.2):

为每个类型、非类型或模板模板参数(包括 模板参数包(其中的14.5.3))分别合成唯一的类型、值或类模板 并将其替换为模板函数类型中该参数的每次出现。

转换后的函数IN模板函数类型为:void func(char*, U1), where U1是一些独特的合成类型。

转换后的函数IN模板函数类型为:void func(char (&buf)[N1], std::size_t), where N1是一些独特的综合价值。

使用转换后的函数模板的函数类型,对另一个模板执行类型推导 如 14.8.2.4 中所述。

因此,让我们尝试在一侧(使用第一个模板作为参数,第二个模板作为参数模板)和相反的一侧执行类型推导。

Case 1.

参数模板:template <std::size_t N> void func(char (&buf)[N], std::size_t size)。 转换后的参数模板:void func(char*, U1).

尝试推断模板参数。 ”char (&buf)[N]“不能从”推断出char*" 类型。U1 不匹配std::size_t键入任一。失败的。

Case 2.

参数模板:template <class T> void func(char* buf, T size)。 转换后的参数模板:void func(char (&buf)[N1], std::size_t).

尝试推断模板参数。参数模板的第一个参数根本不是类型,它与char[]. T应推论为std::size_t.

所以模板II应该更专业一些,应该在下面的代码中选择:

char buf[16];
func(buf, static_cast<std::size_t>(16));

为什么 GCC 5.3 和 Clang 4.0 不是这样?


模板声明没有歧义;以下代码编译并运行正常:

#include <iostream>
#include <string>

using namespace std;

template<class T>
void func(char* buf, T size) {cout<<"void func(char*,T)\n";}
template<size_t N>
void func(char (&buf)[N], std::size_t size) {
  cout<<"void func(char (&)[],size_t)\n";}

int main() {
  char buf[3];
  func(buf, 2);
  func<3>(buf, 2);
  func(reinterpret_cast<char (&)[3]>(buf), 2);
  //next is ambiguous
  //func(reinterpret_cast<char (&)[3]>(buf), size_t(2));
  func<3>(reinterpret_cast<char (&)[3]>(buf), size_t(2));
  return 0;
}

然而,注释掉的调用是不明确的。要消除歧义,请使用:

func<3>(reinterpret_cast<char (&)[3]>(buf), size_t(2));

这工作正常并调用正确的函数。

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

为什么接受数组的 C++ 模板并不比根据 GCC 5.3 和 Clang 4.0 接受指针的模板更专业? 的相关文章

随机推荐

  • 如何不经过身份验证直接向 SMTP 服务器发送邮件?

    我想通过直接连接到将电子邮件直接从脚本发送到 Gmail 电子邮件帐户smtp gmail com 但是 我不希望脚本中包含 gmail 密码 据我所知 Gmail 似乎需要身份验证才能发送任何邮件 包括发送给自己的用户 我的问题是 来自另
  • TFS 远程用户... SSL + 密码还是 VPN?

    我目前的任务是为客户端设置 TFS 服务器 TFS将主要由本地 现场 用户通过内部网络访问 简单 但是我们拥有的少数远程用户怎么办 他们应该通过 VPN 连接还是最好将 TFS 服务器公开并让用户通过 SSL 连接并向 TFS 提供用户名和
  • 使用 TWIG Markdown 转义 HTML 代码

    我正在开发一个博客评论包 我想让用户使用 Markdown 发布一些代码 我正在使用 symfony2 TWIG 和KNP Markdown 捆绑包 https github com KnpLabs KnpMarkdownBundle用于解
  • 在 TypeScript 项目中使用 Path2D 未解决

    我想用新的Path2D https developer mozilla org en US docs Web API Path2D Path2Dapi 在 TypeScript 项目中 但我在 lib es6 d ts 中没有看到它 使用它
  • 还有其他方法可以调整 Blockly 工作区的大小吗?

    我正在努力适应我的Blockly workspace在 div 内 我希望如果页面变小 div 和Blockly workspace它的内部也会更小 我知道有一种方法可以Google在其规定的文档 https developers goog
  • 如何解析 ISO8601 日期 [重复]

    这个问题在这里已经有答案了 我得到了关于这种格式的日期字符串 2011 12 29T09 09 06 0500 如何将其转换为日期对象 尝试这个解决方案 NSString dateString 2011 12 29T09 09 06 050
  • 坐标三角学 - 计算飞行路径弧线的中点

    我正在尝试使用 SVG 在地图上绘制飞行路径 我在 Leaflet 之上使用 d3 但所使用的框架不应该对我的问题产生影响 这是三角函数 http fiddle jshell net zw8TR 26 http fiddle jshell
  • 在没有 Socket.io 的 Backbone.js 应用程序中使用 websockets

    我是 Backbone 的新手 我正在尝试构建一个 Backbone 应用程序来实时绘制和映射数据 我实现了一个 websocket 以下this https github com andrewvc d3 backbone presenta
  • 我可以在 Sql Server 中对一组数字执行按位与运算吗?

    我有一个安全表 其中包含组和用户的列表 每个组和用户都有按位整数权限 对于每个给定的用户 我想对其所有组及其个人权限记录 如果存在 执行按位 AND 操作 当然 我可以轻松地在代码中执行此操作 但我宁愿在数据库中执行此操作 因为我正在查询权
  • 在 Python 中保存 VTK 中的数据数组

    Question 如何从 Python 中的 VTK 中提取数据集数组并将其保存在新文件中 e g 对于具有幅度数据集的 VTKforce 移位 and current仅提取移位并将其保存在较小的文件中 Problem 我在远程服务器上有数
  • Azure BLOB 存储虚拟请求

    I see strange requests when uploading blobs to storage The only methods I use is PutBlob and SetBlobTier But metrics sho
  • Firebase 3.0.1 Web API 查询不起作用,出现 iFrame 安全错误

    我做了一个简单的调用ref once value callback 回调从未被调用 相反 我在 Chrome 控制台中收到此错误 Refused to display https console firebase google com pr
  • 拥有一个 Activity 实例

    我的活动导航和返回堆栈有问题 我希望您能为我解决这个问题 问题 根 Activity gt gt gt SecondActivity gt gt HomeButton 然后 这将带我进入主页 然后我从那里选择 Gmail gt gt 消息
  • 在 makefile 中使用大括号进行变量扩展不起作用

    当我在 shell 上运行以下命令时 它可以正常工作 但如果我把它写在 Makefile 中并用 make 命令调用它 它就不起作用 cp wpa cli 请求者 密码 事件 usr local bin make 命令后出错 cp 无法统计
  • Docker build ARG 始终为空字符串

    我这里有一个 dockerfile FROM golang 1 13 alpine as build ARG DIR somevalue RUN echo DIR 输出是 Sending build context to Docker da
  • Cassandra 3 需要什么版本的 Java

    推荐的Java版本对于卡桑德拉 2 0 https stackoverflow com q 28912016 545127是 Java 7 但是 Cassandra 3 建议或需要哪个版本 具体来说 版本 3 5 一些信息表明需要 Java
  • XML:

    与问题类似 XML那个问号是什么意思 https stackoverflow com questions 39119165 xml what does that question mark mean例如 感叹号是什么意思 下面来自 的含义
  • PGAdmin 显示 Heroku 的数据库量过多

    我正在学习一些后端的东西 我在本地创建了一个测试数据库并填充了一些数据 然后使用以下命令将数据库转储到 SQL 文件 pg dump U USERNAME DATABASE no owner no acl f backup sql 最后将其
  • 在文件搜索中排除 Eclipse/Aptana 中查找的文件类型

    有没有办法在 Aptana 或 Eclipse 文件搜索中排除图像类型 我想搜索所有非图像文件 而不是指定我要搜索的所有文件类型 尝试添加一个 在您不想匹配的模式前面标记 put cgi pm sql 在文件名模式部分中 我正在使用 Ecl
  • 为什么接受数组的 C++ 模板并不比根据 GCC 5.3 和 Clang 4.0 接受指针的模板更专业?

    为什么接下来的两个模板声明不明确 因此两者都不比另一个更专业 我知道这个问题在 Stack Overflow 上已经被多次提出 但通常人们会回答如何解决歧义 而不是回答为什么会发生这种情况 I template