首页 > 解决方案 > `type_alias函数参数中的 {}` VS `char[N]{}`

问题描述

函数定义:

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


正如评论所指出的,case 1不能编译而case 2可以。

我知道alias declarationswithusing不是文本替换(如#define),它是类型的同义词。

但我仍然无法弄清楚如何解释这种情况。然后我给GCC一个try

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]>{});
       ^~~~~~~~~~~~~~~~~~~~~~

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

prog.cc:11:11: 错误:对于函数式强制转换或类型构造,预期为 '('

foo(char[16]{});
      ~~~~^

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


问题:

更新

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

但是Clang可以编译foo(type_alias<char[16]>{});。这似乎是一个错误?

标签: c++gccargumentsclanglanguage-lawyer

解决方案


嗯,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

演示:https ://wandbox.org/permlink/KGf3HVqN3USq6yy8


对于案例2:Clang,GCC,谁符合标准?标准(语言律师)中的任何规范?

两者都接受foo(type_alias<char>[16]{}),但 gcc会警告您(并且由于您使用 编译-Werror,因此此警告会变成错误;)。


推荐阅读