函数参数中的 `type_alias{}` VS `char[N]{}`

2023-12-22

  • 环境:x86-64Clang 6.0.0

函数的定义:

void foo(const char*) {}
  1. foo(char[16]{}); //houston, there is a problem!
  2. foo(type_alias<char[16]>{}); //compile happily

type_alias很简单:

template<typename T>
using type_alias = T;

live demon https://godbolt.org/g/6MmABg


正如评论指出的那样,case 1无法编译case 2 can.

我知道alias declarations with using不是文本替换(比如#define) 并且它是类型的同义词。

但我仍然不知道如何解释这种情况。然后我给GCC a try https://wandbox.org/permlink/RKLfaLiEU4HnW6HS:

prog.cc: In function 'int main()':
prog.cc:11:7: error: expected primary-expression before 'char'
   foo(char[16]{});
       ^~~~
prog.cc:12:7: error: taking address of temporary array
   foo(type_alias<char[16]>{});
       ^~~~~~~~~~~~~~~~~~~~~~

Ah, GCC相反给了我一个错误!然后我用两个编译器的不同版本来编译它:

  • Clang的错误消息case 1 is:

prog.cc:11:11: 错误:函数式转换或类型构造需要 '('

foo(char[16]{});
      ~~~~^
  • Clang lets case 2 pass.

  • GCC禁止这两种情况通过竞争。错误消息case 1 and case 2已在上面列出。

顺便说一句,对于Clang,我也测试过pedantic-errors,但没有任何改变。


问题:

  • For case 2: Clang, GCC,谁符合标准?标准(语言律师)有什么规范吗?
  • For case 1: 谁的错误信息更正确(IOW,符合标准)?

Update

正如 VTT 评论的那样,对于case 1, 它应该是foo(const char[16]{});。为这个错误道歉。

But Clang可以编译foo(type_alias<char[16]>{});。好像是个bug?


Well, type_alias<cv T>{}相当于(cv T){},不至于cv T{}。这种区别很重要,当T是一个数组:

foo((const char[16]){});              // OK
foo(type_alias<const char[16]>{});    // OK

foo(const type_alias<char>[16]{});    // KO
foo(const char[16]{});                // KO

Demo: https://wandbox.org/permlink/KGf3HVqN3USq6yy8 https://wandbox.org/permlink/KGf3HVqN3USq6yy8


对于情况2:Clang、GCC,谁符合标准?标准(语言律师)有什么规范吗?

双方都同意,双方都接受foo(type_alias<char>[16]{}),但是海湾合作委员会warns你关于它(并且因为你编译了-Werror,此警告将变成错误;)。

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

函数参数中的 `type_alias{}` VS `char[N]{}` 的相关文章

  • 以相反的顺序迭代可变参数模板参数

    如果我手动反转传递给它的模板参数的顺序 以下代码将起作用 template
  • SL4 AutoCompleteBox 重复筛选结果问题

    我在 AutoCompleteBox 过滤方面遇到问题 它似乎记住了之前的过滤器 例如 我输入 A 它会返回 1 项 我删除 A 并输入 Z 这应该返回 1 项 问题是它返回 A 过滤器加上 Z 的结果 我删除 Z 并输入 S 这会带回 2
  • DispatcherTimer 未按时执行

    我正在使用 c 中的 DispatchTimer 编写一个时钟应用程序 但由于某些原因 我的时钟似乎时不时地跳过 1 秒 例如 52 秒 gt 54 秒 跳过 53 秒 在我看来 计时器并不是每秒都执行一次 DispatcherTimer
  • C修改printf()输出到文件

    有没有办法修改printf为了将字符串输出到文件而不是控制台 我尝试在互联网上查找一些内容 发现了类似的电话dup dup2 and fflush这可能与此有关 EDIT 也许我不清楚 问题是这是C考试问题 问题如下 解释一个通常将字符串输
  • 为什么opencv videowriter这么慢?

    你好 stackoverflow 社区 我有一个棘手的问题 我需要你的帮助来了解这里发生了什么 我的程序从视频采集卡 Blackmagic 捕获帧 到目前为止 它工作得很好 同时我用 opencv cv imshow 显示捕获的图像 它也工
  • 切换图片框可见性 C#

    为什么图片框控件的可见性属性在这里不起作用 我最初将它们设置为 false 以便在屏幕加载时它们不可见 但后来我想切换这个 我已完成以下操作 但似乎不起作用 这是一个 Windows 窗体应用程序 private void Action w
  • 使用不带参数的 Split() 时,默认分隔符是什么?

    所以我看了看String Split 今天 C 中的方法 我意识到你也可以向它传递零参数 这是我从未考虑过的 使用时默认的分隔符是什么Split 没有任何参数 如果没有值 则为空白 来源自here https msdn microsoft
  • 返回 int& 的函数[重复]

    这个问题在这里已经有答案了 我在网上查了一下发现一篇试图解释的文章std move和右值 http thbecker net articles rvalue references section 01 html并发现了一些我实在无法掌握的东
  • 在 GCC 和 Clang 下,使用 lambda 的简单 RAII 包装器的复制初始化意外失败

    我在创建一个简单的 RAII 包装器时遇到了一个意想不到的问题 更不用说下面代码的逻辑不完整性了 复制构造函数和赋值运算符未删除等 这意味着是一个SSCCE 令我印象深刻的是复制初始化我的包装器与临时 lambda 的结果会导致编译错误 而
  • C# 中附加/分离事件处理程序的不同方式有什么区别

    我的问题有两个部分 首先 我们可以通过以下两种方式附加事件处理程序 myObject MyEvent new EventHandler MyHandler myObject MyEvent MyHandler 据我了解 这两者是等价的 在第
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • 指示泛型返回动态类型的对象

    这个问题是我原来问题的后续问题here https stackoverflow com questions 2541184 using a type object to create a generic 假设我有以下泛型类 简化 class
  • 使用scanf()时如何区分整数和字符

    我只是使用该功能scanf 代码如下 scanf d a printf d a 当我输入1时 它会像我想要的那样打印1 但即使我输入 1a 它也会像以前一样打印 1 当用户输入非整数时 例如 2 3 12ab 1 a 我想向用户显示 输入整
  • 如何将字符串转换为 Indian Money 格式?

    我正在尝试将字符串转换为印度货币格式 例如如果输入为 1234567 则输出应为 12 34 567 我编写了以下代码 但它没有给出预期的输出 CultureInfo hindi new CultureInfo hi IN string t
  • 无法通过 LINQ to Entities 使用某些功能?

    我正在尝试使用 LINQ 查询在项目上实现搜索功能 由于数据有时包含带有重音符号和其他符号的字符 因此我创建了一种方法来删除这些字符以进行搜索 这是我的代码 var addresses from a in db Addresses join
  • 将 bignum 类型结构转换为人类可读字符串的有效方法是什么?

    我有一点问题 为了增长我的 C 知识 我决定尝试实现一个基本的 bigint 库 bigint 结构的核心将是一个 32 位整数数组 选择它们是因为它们适合寄存器 这将允许我在数字之间进行操作 这些操作将在 64 位整数中溢出 这也将适合寄
  • 如何使用 ASP.NET Web 表单从代码隐藏中访问更新面板内的文本框、标签

    我在更新面板中定义了一些控件 它们绑定到中继器控件 我需要根据匿名字段隐藏和显示用户名和国家 地区 但问题是我无法以编程方式访问更新面板中定义的控件 我如何访问这些控件 我也在网上查找但找不到很多参考资料 下面是来自aspx页面和 cs页面
  • 程序退出后,TcpListener Socket 仍处于活动状态

    当我的程序退出时 我试图停止 TCP 侦听器 我不关心套接字或任何活动客户端套接字上当前活动的任何数据 套接字清理代码本质上是 try myServer Server Shutdown SocketShutdown Both catch E
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使
  • 使用剪贴板 SetText 换行

    如何使用 SetText 方法添加换行符 I tried Clipboard SetText eee n xxxx 但当我将剪贴板数据粘贴到记事本中时 它没有给我预期的结果 预期结果 eee xxxx 我怎样才能做到这一点 Windows

随机推荐