Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中的Throw和三元运算符+;_C++_Operators_Ternary Operator - Fatal编程技术网

C++ C+中的Throw和三元运算符+;

C++ C+中的Throw和三元运算符+;,c++,operators,ternary-operator,C++,Operators,Ternary Operator,以下代码使用G++4.6.1编译,但不使用Visual Studio 2008 return (m_something == 0) ? throw std::logic_error("Something wrong happened") : m_something; 事实是VisualStudio编译器执行内部崩溃 我想知道这是不是标准C++,为什么它不使用VisualStudio编译,但是用G++ +?< /P> < P> COMUO编译它没有错误(这里是我的最小可编译测试用例):

以下代码使用G++4.6.1编译,但不使用Visual Studio 2008

return (m_something == 0) ? 
    throw std::logic_error("Something wrong happened") : m_something;
事实是VisualStudio编译器执行内部崩溃


我想知道这是不是标准C++,为什么它不使用VisualStudio编译,但是用G++ +?< /P> < P> COMUO编译它没有错误(这里是我的最小可编译测试用例):

这是标准允许的很好的证据。MSVC崩溃的事实也是如此,而不是因为一个错误而彻底失败

此外,它似乎在VC++2010中已修复

R:\>cl ternarythrowtest.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

ternarythrowtest.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:ternarythrowtest.exe
ternarythrowtest.obj
和x64版本:

R:\>cl ternarythrowtest.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

ternarythrowtest.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:ternarythrowtest.exe
ternarythrowtest.obj

如果可能的话升级你的编译器,这远不是唯一的错误,2010。< /P> < P>它是标准C++。条件表达式中的then/else表达式之一(或两者)可以改为THOW表达式(C++98 5.16/2)


如果Visual Studio在编译时崩溃。。。那似乎很不幸

来自2月11日的C++11草案

§5.16/2如果第二个或第三个操作数的类型(可能是cv限定的)为void,则对第二个和第三个操作数执行左值到右值(4.1)、数组到指针(4.2)和函数到指针(4.3)的标准转换,并且以下之一应保持不变:
-第二个或第三个操作数(但不是两者)是一个抛出表达式(15.1);结果属于另一种类型,是一个PR值。
-第二个和第三个操作数都具有void类型;结果为void类型,是一个prvalue。[注:这包括两个操作数都是抛出表达式的情况。-结束注]


看来
throw
计算为
void
,这是允许的。

内部崩溃可以被视为Visual Studio的一个bug。编译器永远不会因为正在编译的代码而崩溃

这是三元运算符的一个非常奇怪的用法,在返回之前使用一个简单的if是一个更好的习惯用法:

if(m_something == 0)
    throw std::logic_error("Something wrong happened");

return m_something;

§5.16/2允许这两个表达式在C++11中都是抛出表达式。@Mat:oops,你说得很对,这里的文本没有改变,第二个选项也允许这两个表达式在C++98中抛出。事实上,这可能是因为C++11合规性,请参阅@MooingDuck的答案。@AndréCaron:这无法解释“内部编译器错误”。看看John的答案,C++98中也允许这样做。我是@fmorence团队的成员,我是那个用三元运算符表达式抛出的Microsoft编译器崩溃的人。我们试图弄清楚它是否是标准的,而不是这是否是微软编译器中的一个bug(显然有一个bug,因为它崩溃了)。@AndréCaron:好吧,这是C++98,不是C++11的合规性问题,所以它肯定能工作。的确:-)。不幸的是,我们目前还停留在Qt4.7上,而且我们支持Windows,所以我们停留在VS2008的编译器上。C++11与VS2008几乎没有什么关系(除了这不是C++11规则,自C++98以来没有变化,请参见John的回答)。我没有一份C++03草稿(用于VS2008)的副本可以引用,否则我会引用它。你说得对,它不一定适用于VS2008。但是,不管这是有效代码还是不符合标准,当编译器因内部编译器错误(VC就是这样做的,IIUC)而崩溃时,那就是编译器中的错误。编译器即使对于错误代码也应该发出有意义的消息,而不是崩溃报告。请记住,这是条件运算符,它恰好是三元运算符。是的,当规范中没有“三元”时,我感到困惑。有一段时间(在c++11和c++14之间)从三元组抛出是编写可能在编译时失败的constexpr函数的唯一方法。
if(m_something == 0)
    throw std::logic_error("Something wrong happened");

return m_something;