在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。 所以, throw
expression式的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>
所以我们实际上可以validationthrow
expression式是void
types(是的,在其他答案中提到的Standard引用validation这不是实现特定的结果 – 虽然gcc很难打印有价值的信息)