函数调用参数中的构造函数样式转换 [英] Constructor-style casting in function call parameters

查看:1432
本文介绍了函数调用参数中的构造函数样式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

int main(){
foo(unsigned char(0));
}

错误是:




  • 错误:gcc之前的未签名之前的预期主表达式。

  • error:expected'('for function-style cast or type construction for clang



这三个语法是正确的:

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

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

//无符号
foo (0));

//别名unsigned char
typedef unsigned char uchar;
foo(uchar(0));
}

因此,类型中的空格显然是这里的怪。



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

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

int main(){
foo(unsigned char {0});
}

但仍然:




  • 错误:gcc之前的unsigned之前的预期主表达式

  • error:expected'('for function-style cast or type construction for clang



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



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

解决方案


[C ++ 11:5.2.3 / 1] code> simple-type-specifier (7.1.6.2)或 typename-specifier (14.6)后跟括号 >构造给定表达式列表的指定类型的值。 [..]


检查语法,我们看到获得<$ c $



作为证据,可以从 simple-type-specifier 产品中选择 unsigned char 揭开表10正在说明相反的谣言,我可能自己刚刚开始(:P),表标题说说明符(注意可选复数),并参考以下段落:


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


允许在某些情况下:


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


…但没有迹象表明这是功能符号的情况,它清楚地说明 simple-type-specifier



因此,GCC正确,Visual Studio错误。至于为什么这是case ...好吧,我不知道。我怀疑我们可以想出一些不明确的边缘情况,但是 Casey 在下面的评论中提出了一个好点,与函数调用语法不一致,因为函数名称中不能有空格。


I don't understand why the following code fails to compile when using constructor-style casting:

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

int main(){
  foo(unsigned char(0));
}

The errors are:

  • error: expected primary-expression before ‘unsigned’ for gcc.
  • error: expected '(' for function-style cast or type construction for clang

However these three syntaxes are correct:

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));
}

So the space in the type is obviously to blame here.

I thought it might be somehow related to our old friend the most vexing parse, so I tried the uniform initialization syntax, which is supposed to get rid of this sort of ambiguities, but no luck:

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

int main(){
  foo(unsigned char{0});
}

But still:

  • error: expected primary-expression before ‘unsigned’ for gcc.
  • error: expected '(' for function-style cast or type construction for clang

So my question is why is it not allowed to have a type containing a space in function-style casts? It doesn't look ambiguous to me.

note: I know I can write foo<unsigned char>(0), but it doesn't answer the question ;)

解决方案

[C++11: 5.2.3/1]: A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. [..]

Examining the grammar, we see that the only way to get unsigned char from the simple-type-specifier production is by concatenating two of them.

As evidence debunking the rumour that table 10 is stating the contrary, which I may myself have started a short while ago (:P), the table heading says "specifier(s)" (note the optional plural), and refer to the below passage:

[C++11: 5.2.3/2]: [..] Table 10 summarizes the valid combinations of simple-type-specifiers and the types they specify. (emphasis mine)

Now, combining simple-type-specifiers is allowed in some cases:

[C++11: 7.1.6.2/3]: When multiple simple-type-specifiers are allowed, they can be freely intermixed with other decl-specifiers in any order. [..]

… but there's no indication that this is the case with functional notation, which clearly states "a simple-type-specifier" — singular.

Therefore GCC is correct, and Visual Studio is wrong.

As for why this is the case... well, I don't know. I suspect we could come up with some ambiguous edge case, but Casey makes a good point in the comments below that allowing this would be inconsistent with function call syntax, since names of functions cannot have spaces in them.

这篇关于函数调用参数中的构造函数样式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆