在C ++中,如果throw是一个expression式,它的types是什么?

我在一个简短的讨论中把它提到了reddit:

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

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

throw "error" 

是一个expression。 在C ++标准中,这在主文本和语法中都是相当清楚的。 然而,至less对我来说不明确的是什么types的expression? 我猜“ 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 } 

编译器对// 1没有任何问题,但由于条件运算符中的types是不同的,所以// 2上的barfed。 所以, throwexpression式的types似乎不是无效的。

那是什么?

如果您回答,请使用标准的报价备份您的报表。


事实certificate,这并不是像条件操作符如何处理throwexpression式那样的一个throwexpression式的types – 这在我今天之前肯定是不知道的。 感谢所有回答的人,特别是David Thornley。

按照标准5.16第2段第一点,“第二个或第三个操作数(但不是两个)是一个投掷expression式(15.1);结果是另一个的types,是一个右值。 因此,条件运算符不关心throw-expression是什么types,而只是使用其他types。

实际上,15.1,第1段明确指出:“抛出expression式是voidtypes的。

“抛出expression式是voidtypes的”

ISO14882第15节

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

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

– 第二个或第三个操作数(但不是两个)是一个throwexpression式; 结果是另一种的types,是一个右值。

– 第二个和第三个操作数都有voidtypes; 结果是voidtypes,是一个右值。 [注意:这包括两个操作数都是throw-expressions的情况。 – 结束注意]

所以, //1你在第一个案件中, //2 ,你违反了“下列条件之一”,因为在这种情况下,他们都没有。

你可以让一台打印机为你吐出来 :

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

基本上缺lessPrintType的实现将导致编译错误报告说:

未定义模板的隐式实例化PrintType<void>

所以我们实际上可以validationthrowexpression式是voidtypes(是的,在其他答案中提到的Standard引用validation这不是实现特定的结果 – 虽然gcc很难打印有价值的信息)