<bdo id='oemlU'></bdo><ul id='oemlU'></ul>

      1. <legend id='oemlU'><style id='oemlU'><dir id='oemlU'><q id='oemlU'></q></dir></style></legend>
      2. <small id='oemlU'></small><noframes id='oemlU'>

      3. <i id='oemlU'><tr id='oemlU'><dt id='oemlU'><q id='oemlU'><span id='oemlU'><b id='oemlU'><form id='oemlU'><ins id='oemlU'></ins><ul id='oemlU'></ul><sub id='oemlU'></sub></form><legend id='oemlU'></legend><bdo id='oemlU'><pre id='oemlU'><center id='oemlU'></center></pre></bdo></b><th id='oemlU'></th></span></q></dt></tr></i><div id='oemlU'><tfoot id='oemlU'></tfoot><dl id='oemlU'><fieldset id='oemlU'></fieldset></dl></div>

        <tfoot id='oemlU'></tfoot>
      4. 函数调用参数中的构造函数类型转换

        Constructor-style casting in function call parameters(函数调用参数中的构造函数类型转换)
        <legend id='s1w5o'><style id='s1w5o'><dir id='s1w5o'><q id='s1w5o'></q></dir></style></legend><tfoot id='s1w5o'></tfoot>

          <small id='s1w5o'></small><noframes id='s1w5o'>

            • <bdo id='s1w5o'></bdo><ul id='s1w5o'></ul>

                    <tbody id='s1w5o'></tbody>

                  <i id='s1w5o'><tr id='s1w5o'><dt id='s1w5o'><q id='s1w5o'><span id='s1w5o'><b id='s1w5o'><form id='s1w5o'><ins id='s1w5o'></ins><ul id='s1w5o'></ul><sub id='s1w5o'></sub></form><legend id='s1w5o'></legend><bdo id='s1w5o'><pre id='s1w5o'><center id='s1w5o'></center></pre></bdo></b><th id='s1w5o'></th></span></q></dt></tr></i><div id='s1w5o'><tfoot id='s1w5o'></tfoot><dl id='s1w5o'><fieldset id='s1w5o'></fieldset></dl></div>

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

                  问题描述

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

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

                  错误是:

                  • 错误:gcc 的无符号"之前的预期主表达式.
                  • 错误:函数式转换或类型构造的预期'(' for clang
                  • 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});
                  }
                  

                  但仍然:

                  • 错误:gcc 的无符号"之前的预期主表达式.
                  • 错误:函数式转换或类型构造的预期'(' for clang
                  • 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.

                  注意:我知道我可以写foo(0),但它没有回答问题;)

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

                  推荐答案

                  [C++11: 5.2.3/1]: 简单类型说明符 (7.1.6.2) 或 类型名称说明符em> (14.6) 后跟带括号的 expression-list 构造给定表达式列表的指定类型的值.[..]

                  [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. [..]

                  检查语法,我们发现从 simple-type-specifier 产生式中获取 unsigned char 的唯一方法是连接它们中的两个.

                  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.

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

                  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]: [..] 表 10 总结了 的有效组合>simple-type-specifiers 和它们指定的类型.(强调我的)

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

                  现在,在某些情况下允许组合simple-type-specifiers:

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

                  [C++11: 7.1.6.2/3]: 当允许多个 simple-type-specifiers 时,它们可以与其他 自由混合声明说明符 以任何顺序.[..]

                  [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. [..]

                  …但没有迹象表明这是功能符号的情况,它清楚地指出a simple-type-specifier" —单数.

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

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

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

                  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.

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

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Constructor initialization Vs assignment(构造函数初始化 Vs 赋值)
                  Is a `=default` move constructor equivalent to a member-wise move constructor?(`=default` 移动构造函数是否等同于成员移动构造函数?)
                  Has the new C++11 member initialization feature at declaration made initialization lists obsolete?(声明时新的 C++11 成员初始化功能是否使初始化列表过时了?)
                  Order of constructor call in virtual inheritance(虚继承中构造函数调用的顺序)
                  How to use sfinae for selecting constructors?(如何使用 sfinae 选择构造函数?)
                  Initializing a union with a non-trivial constructor(使用非平凡的构造函数初始化联合)
                    <bdo id='tqj68'></bdo><ul id='tqj68'></ul>
                    <tfoot id='tqj68'></tfoot>
                    <i id='tqj68'><tr id='tqj68'><dt id='tqj68'><q id='tqj68'><span id='tqj68'><b id='tqj68'><form id='tqj68'><ins id='tqj68'></ins><ul id='tqj68'></ul><sub id='tqj68'></sub></form><legend id='tqj68'></legend><bdo id='tqj68'><pre id='tqj68'><center id='tqj68'></center></pre></bdo></b><th id='tqj68'></th></span></q></dt></tr></i><div id='tqj68'><tfoot id='tqj68'></tfoot><dl id='tqj68'><fieldset id='tqj68'></fieldset></dl></div>
                  • <small id='tqj68'></small><noframes id='tqj68'>

                      <tbody id='tqj68'></tbody>

                          1. <legend id='tqj68'><style id='tqj68'><dir id='tqj68'><q id='tqj68'></q></dir></style></legend>