Why doesn't this enum convert to int?

后端 未结 3 834
陌清茗
陌清茗 2020-12-14 07:21

Why does the following code not compile under g++ (C++14), MSVC (C++14), or ARM (C++03)?

The named Error instance calls the integer constructor, but the anonymous Er

相关标签:
3条回答
  • 2020-12-14 08:11

    This comes from the same place as "The Most Vexing Parse" - the rule that if it can be a declaration, it is a declaration.
    And surprisingly, you're allowed to put parentheses around the identifier in a variable declaration.
    (I have no idea why, but I'm guessing that it simplified C's parser back in the day.)

    The following are all valid declarations of int variables:

    int (foo);
    int (bar) = 0;
    int (baz)(3);
    int (twaddle)(baz);
    
    0 讨论(0)
  • 2020-12-14 08:11

    main.cpp:19:18: error: no matching function for call to 'Error::Error()'
    Error(value_1);

    The compiler tries to call the non-existent default constructor Error::Error() because it sees

    Error(value_1);
    

    as a variable declaration

    Error  value_1;
    

    A declaration is allowed to have redundant parenthesis.

    0 讨论(0)
  • 2020-12-14 08:26

    The problem is that code

    Error(value_1);
    

    is a declaration of a variable value_1 of type Error.

    This is a legacy from C language that uses expressions as part of type declaration.

    For example int *i is a pointer to int because it says that expression *i should evaluate to type int. More examples of this:

    • int (*func)() is a pointer to function returning int because expression (*func)() evaluates to type int.
    • int *p[8] is an array of pointers to int because expression *p[x] evaluates to type int.
    • int (*p)[8] is a pointer to array of 8 int's (int[8]) because expression (*p)[x] evaluates to type int.
    • int (*(*p[8])())() is an array of 8 pointers to functions returning pointers to a function returning int because expression (*(*p[x])())() evaluates to type int.

    Similarly int (i) is a plain variable of type int as expression (i) evaluates to type int.

    And so because C++ inherits this from C, it uses parenthesis as part of type declaration, but also adds more syntax on top, leading to some unexpected results.

    The rule applied by C++ here says to treat everything that can be a declaration as a declaration.


    Similar confusion if often caused by code like this:

    Error ec();
    

    which is a forward declaration of a function ec that returns Error.

    0 讨论(0)
提交回复
热议问题