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

Constructor-style casting in function call parameters

本文关键字:样式 转换 构造函数 参数 函数调用      更新时间:2023-10-16

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

template<typename T> void foo(const T& t){}
int main(){
  foo(unsigned char(0));
}

错误为:

  • gcc的CCD_ 1
  • clang的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));
}

所以类型中的空格显然是罪魁祸首。

我认为这可能与我们的老朋友最麻烦的解析有关,所以我尝试了统一的初始化语法,它应该可以消除这种歧义,但没有成功:

template<typename T> void foo(const T& t){}
int main(){
  foo(unsigned char{0});
}

但仍然:

  • 用于gcc的CCD_ 3
  • clang的error: expected '(' for function-style cast or type construction

所以我的问题是,为什么不允许在函数样式转换中有一个包含空格的类型?在我看来,这并不含糊。

注意:我知道我能写foo<unsigned char>(0),但它不能回答问题;)

[C++11: 5.2.3/1]:简单类型说明符(7.1.6.2)或类型名说明符达式列表构造给定表达式列表的指定类型的值[..]

通过检查语法,我们发现从简单类型说明符生成中获取unsigned char的唯一方法是连接其中两个。

作为揭穿表10所述相反谣言的证据,我可能自己不久前就已经开始了(:p),表标题上写着"说明符"(注意可选复数),并参考以下段落:

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

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

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

…但没有迹象表明函数表示法就是这样,它清楚地表明"a简单类型说明符"—单数的

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

至于为什么会出现这种情况。。。嗯,我不知道。我怀疑我们可能会遇到一些模糊的边缘情况,但Casey在下面的评论中提出了一个很好的观点,即允许这样做与函数调用语法不一致,因为函数名称中不能有空格。