函数调用参数中的构造函数样式转换

Thi*_*aut 19 c++ casting c++11

我不明白为什么以下代码在使用构造函数样式的转换时无法编译:

template<typename T> void foo(const T& t){}

int main(){
  foo(unsigned char(0));
}
Run Code Online (Sandbox Code Playgroud)

错误是:

  • error: expected primary-expression before ‘unsigned’ 对于gcc.
  • error: expected '(' for function-style cast or type construction 为了铿锵

但是这三种语法是正确的:

template<typename T> void foo(const T& t){}

int main(){
  // c-style cast
  foo((unsigned char)0);

  // without unsigned
  foo(char(0));

  // aliased unsigned char
  typedef unsigned char uchar;
  foo(uchar(0));
}
Run Code Online (Sandbox Code Playgroud)

所以这种类型的空间显然应该归咎于此.

我认为它可能与我们的老朋友有点相关的最令人烦恼的解析,所以我尝试了统一初始化语法,这应该摆脱这种模糊,但没有运气:

template<typename T> void foo(const T& t){}

int main(){
  foo(unsigned char{0});
}
Run Code Online (Sandbox Code Playgroud)

但仍然:

  • error: expected primary-expression before ‘unsigned’ 对于gcc.
  • error: expected '(' for function-style cast or type construction 为了铿锵

所以我的问题是为什么不允许在函数式转换中包含一个包含空格的类型?它对我来说并不含糊.

注意:我知道我可以写foo<unsigned char>(0),但它没有回答这个问题;)

Lig*_*ica 16

[C++11: 5.2.3/1]:简单型说明符(7.1.6.2)或类型名称说明符后跟带括号的(14.6)表达式列表构建体给出的表达式列表中指定的类型的值.[..]

检查语法,我们看到unsigned char简单类型说明符生成中获得的唯一方法是连接其中两个.

作为揭示表10相反的谣言的证据,我可能在不久前就开始了(:P),表标题是"说明符"(注意可选的复数形式),并参考下面的内容通道:

[C++11: 5.2.3/2]: [...]表10总结了简单类型说明符的有效组合及其指定的类型.(强调我的)

现在,在某些情况下允许组合简单类型说明符:

[C++11: 7.1.6.2/3]:当允许多个简单类型说明符时,它们可以以任何顺序与其他decl-specifier自由混合.[..]

...但是没有迹象表明这是功能符号的情况,它清楚地表明" 一个 简单类型说明符 " - 单数.

因此GCC是正确的,Visual Studio是错误的.

至于为什么会这样......好吧,我不知道.我怀疑我们可能会提出一些模棱两可的边缘情况,但是Casey在下面的注释中提出了一个很好的观点,即允许这与函数调用语法不一致,因为函数名称中不能包含空格.

  • 好吧,至少VS又回来了.一切都与世界一致. (4认同)