c++ - `type_alias函数参数中的 {}` VS `char[N]{}`
问题描述
- 环境:x86-64 Clang 6.0.0
函数定义:
void foo(const char*) {}
foo(char[16]{}); //houston, there is a problem!
foo(type_alias<char[16]>{}); //compile happily
type_alias
很简单:
template<typename T>
using type_alias = T;
正如评论所指出的,case 1
不能编译而case 2
可以。
我知道alias declarations
withusing
不是文本替换(如#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反而给了我一个错误!然后我用两个编译器的不同版本编译它:
- Clang的错误信息
case 1
是:
prog.cc:11:11: 错误:对于函数式强制转换或类型构造,预期为 '('
foo(char[16]{}); ~~~~^
Clang让我们
case 2
过去。GCC禁止这两种情况通过竞争。上面列出了
case 1
和的错误消息。case 2
顺便说一句,对于Clang,我也用 进行了测试pedantic-errors
,但没有任何改变。
问题:
- For
case 2
: Clang , GCC , 谁符合标准?标准(语言律师)中的任何规范? - For
case 1
:谁的错误信息更正确(IOW,符合标准)?
更新
正如 VTT 评论的那样,对于case 1
,它应该是foo(const char[16]{});
。为这个错误道歉。
但是Clang可以编译foo(type_alias<char[16]>{});
。这似乎是一个错误?
解决方案
嗯,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
,因此此警告会变成错误;)。