In C++, if throw is an expression, what is its type?

后端 未结 4 556
耶瑟儿~
耶瑟儿~ 2020-12-07 13:29

I picked this up in one of my brief forays to reddit:

http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/

Basically, the a

相关标签:
4条回答
  • 2020-12-07 14:08

    "A throw-expression is of type void"

    ISO14882 Section 15

    0 讨论(0)
  • 2020-12-07 14:11

    You can have a type printer spit it out for you :

    template<typename T>
    struct PrintType;
    
    int main()
    {
        PrintType<decltype(throw "error")> a; 
    }
    

    Basically the lack of implementation for PrintType will cause the compilation error report to say :

    implicit instantiation of undefined template PrintType<void>

    so we can actually verify that throw expressions are of type void (and yes, the Standard quotes mentioned in other answers verify that this isn't an implementation specific outcome - though gcc has a hard time printing valuable info)

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

    According to the standard, 5.16 paragraph 2 first point, "The second or the third operand (but not both) is a throw-expression (15.1); the result is of the type of the other and is an rvalue." Therefore, the conditional operator doesn't care what type a throw-expression is, but will just use the other type.

    In fact, 15.1, paragraph 1 says explicitly "A throw-expression is of type void."

    0 讨论(0)
  • 2020-12-07 14:30

    From [expr.cond.2] (conditional operator ?:):

    If either the second or the third operand has type (possibly cv-qualified) void, then the lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed on the second and third operands, and one of the following shall hold:

    — The second or the third operand (but not both) is a throw-expression; the result is of the type of the other and is an rvalue.

    — Both the second and the third operands have type void; the result is of type void and is an rvalue. [ Note: this includes the case where both operands are throw-expressions. — end note ]

    So, with //1 you were in the first case, with //2, you were violating "one of the following shall hold", since none of them do, in that case.

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