2012-10-11 2 views
78

throw()noexcept 사이에 다른 점이 있습니까?C++ 03 throw() 지정자의 차이점 C++ 11 noexcept

Wikipedia C++11이 기사에서는 C++ 03 throw specifier가 더 이상 사용되지 않는다고 제안합니다.
그렇다면 noexcept은 컴파일 할 때이 모든 것을 다루기에 충분합니까?

[참고 : 나는 this questionthis article 언급하지만, 중단의 고체 이유를 가지고 없습니다.]

+6

[nice article] (http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/)에 부합하면'noexcept'도 런타임 검사를 유발할 수 있습니다. 가장 큰 차이점은'noexcept'를 깨면'std :: terminate'가 발생하고'throw'를 깨면'std :: unexpected'가 발생한다는 것입니다. 또한 이러한 경우에 약간 다른 스택 풀기 동작. – Fiktik

답변

101

예외 지정자는 exception specifiers are generally a terrible idea 때문에 사용되지 않는. noexcept이 예외 지정자를 사용하는 것이 합리적으로 유용하기 때문에 추가되었습니다. 이 예외가 아닌 예외를 알리는 시점을 아는 것입니다. 따라서 이진 선택이됩니다. 즉, 던질 함수와 던지지 않을 함수입니다.

noexceptnoexcept이 더 강력하기 때문에 throw()이 아닌 모든 throw 지정자를 제거하는 것보다 추가되었습니다. noexcept은 컴파일 타임이 부울로 해석되는 매개 변수를 가질 수 있습니다. 부울이 참이면 noexcept이 붙습니다. 부울이 거짓이면 noexcept이 붙지 않으며 함수가 throw 될 수 있습니다.

따라서,이 같은 작업을 수행 할 수 있습니다

struct<typename T> 
{ 
    void CreateOtherClass() { T t{}; } 
}; 

CreateOtherClass 던져 예외를합니까? 만약 T의 기본 생성자가 할 수 있습니다. 우리는 어떻게 말합니까? 이처럼 : 지정된 형태의 기본 생성자가 발생 IFF에 따라서

struct<typename T> 
{ 
    void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; } 
}; 

, CreateOtherClass()가 발생합니다. 예외 지정자의 주요 문제점 중 하나 인 호출 스택을 전파 할 수없는 문제가 수정되었습니다.

throw()으로는이 작업을 수행 할 수 없습니다.

+0

+1 어쨌든 유용한 답. 왜'noexcept'를 사용하고 싶은지에 대한 대답을 찾고 있습니다. 난'throw()'지정자를 절대로 사용하지 않았고'noexcept'가 실제로 컴파일러 검사 문서가 아닌 다른 이점을 제공하는지 확인하려고 시도했습니다. – hmjd

+0

그냥 찾았습니다. http://stackoverflow.com/questions/10787766/when-should--allyally-use-noexcept ... – hmjd

+0

@hmjd : "* noexcept를 사용하려는 이유를 묻는 답변을 계속 검색하고 있습니다. * * "질문에 * 답한 것이 아니기 때문에 여기에 대한 답을 찾지 못할 것입니다. –

29

noexcept은 컴파일 할 때 확인되지 않습니다.

구현시 표현식을 거부해서는 안되며, 실행될 때 포함 함수가 허용하지 않는 예외를 throw하거나 throw 할 수 있기 때문입니다.

때 하나 terminate를 호출하고 인접 통화 unexpected 및 예외 처리의 후자의 스타일이 효율적으로 사용되지 않습니다있는 유일한 차이점은 예외를 던져 noexcept 또는 throw() 시도를 선언하는 기능.

1

동적 예외 사양을 위반했을 때 std :: unexpected()가 C++ 런타임에 의해 호출되었습니다. 예외 사양에서이 유형의 예외를 금지하는 함수에서 예외가 throw됩니다.

std :: unexpected()는 프로그램에서 직접 호출 할 수도 있습니다.

두 경우 모두 std :: unexpected는 현재 설치된 std :: unexpected_handler를 호출합니다. 기본 std :: unexpected_handler는 std :: terminate를 호출합니다.