在C++中,如果throw是一个表达式,它的类型是什么?

115 c++ throw

我在我的一个简短的尝试中选择了这个来reddit:

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

基本上,作者指出在C++中:

throw "error"
Run Code Online (Sandbox Code Playgroud)

是一种表达.这在C++标准中实际上非常清楚地阐明了,包括主文本和语法.但是,至少对我来说不清楚的是表达的类型是什么?我猜到了" void",但是有点尝试使用g ++ 4.4.0和Comeau产生了这样的代码:

    void f() {
    }

    struct S {};

    int main() {
        int x = 1;
        const char * p1 = x == 1 ? "foo" : throw S();  // 1
        const char * p2 = x == 1 ? "foo" : f();        // 2
    }
Run Code Online (Sandbox Code Playgroud)

编译器对// 1没有问题,但在// 2上进行了禁止,因为条件运算符中的类型不同.所以throw表达式的类型似乎不是空的.

那是什么?

如果您回答,请使用标准中的引号备份您的陈述.


事实证明,抛出表达式的类型并不像条件运算符如何处理throw表达式那样 - 这在今天之前我当然不知道.感谢所有回复的人,尤其是David Thornley.

Dav*_*ley 96

根据标准,5.16第2段第一点,"第二或第三操作数(但不是两者)是一个throw-expression(15.1);结果是另一个的类型,是一个rvalue." 因此,条件运算符不关心throw-expression的类型,而只关注其他类型.

事实上,15.1,第1段明确地说"抛出表达式是无效的".

  • 好的 - 我想我们有一个胜利者. (9认同)
  • 让我感到惊讶的是,他们想到了这个案子并且做出了一些合理的事情. (4认同)

Dra*_*mon 31

"throw-expression的类型为void"

ISO14882第15节

  • @Neil,不是因为根据C++/5.16/2,条件运算符的第二和第三个操作数可以是`void的类型 (2认同)

Mar*_*utz 13

从[expr.cond.2](条件运算符?:):

如果第二个或第三个操作数的类型(可能是cv-quali fi ed)为void,则在第二个和第三个操作数上执行左值到右值,数组到指针和函数到指针的标准转换,以下之一应持有:

- 第二个或第三个操作数(但不是两个)是一个throw-expression; 结果是另一个的类型,是一个右值.

- 第二个和第三个操作数都有类型void; 结果是void类型,是一个rvalue.[注意:这包括两个操作数都是throw-expressions的情况. - 结束说明]

因此,//1如果你是第一个案件,//2那么你违反了"以下其中一个人",因为在这种情况下他们都没有.