- 필자가 결코 알지 못할 함수의 많은 예가 있지만 컴파일러가 스스로 결정할 수는 없습니다. 그러한 모든 경우에 함수 선언에 noexcept를 추가해야합니까?
noexcept
함수 인터페이스의 일부이므로 까다 롭습니다. 특히 라이브러리를 작성하는 경우 클라이언트 코드가 noexcept
속성에 따라 달라질 수 있습니다 . 기존 코드가 손상 될 수 있으므로 나중에 변경하기 어려울 수 있습니다. 응용 프로그램에서만 사용하는 코드를 구현할 때는 걱정할 필요가 없습니다.
던질 수없는 함수가 있다면, 유지를 원하는지 noexcept
또는 향후 구현을 제한 할 것인지 스스로에게 물어보십시오 . 예를 들어 예외 (예 : 단위 테스트)를 발생시켜 잘못된 인수에 대한 오류 검사를 수행하거나 예외 사양을 변경할 수있는 다른 라이브러리 코드에 의존 할 수 있습니다. 이 경우 보수적이고 생략하는 것이 더 안전합니다 noexcept
.
반면에, 함수가 절대로 던져지지 않아야하고 그것이 사양의 일부인 것이 정확하다고 확신하는 경우이를 선언해야합니다 noexcept
. 그러나 noexcept
구현이 변경 될 경우 컴파일러는 위반을 감지 할 수 없습니다 .
- 어떤 상황에서 noexcept의 사용에 대해 더주의를 기울여야하며, 어떤 상황에서 묵시적인 noexcept (false)로 벗어날 수 있습니까?
가장 큰 영향을 미치기 때문에 집중해야 할 네 가지 기능 클래스가 있습니다.
- 이동 작업 (할당 연산자 이동 및 생성자 이동)
- 스왑 작업
- 메모리 할당 해제 기 (운영자 삭제, 운영자 삭제 [])
- 소멸자 (
noexcept(true)
당신이 그들을 만들지 않는 한 이것들은 암시 적으로 있지만 noexcept(false)
)
이러한 함수는 일반적으로이어야 noexcept
하며 라이브러리 구현 noexcept
에서이 속성 을 사용할 수 있습니다 . 예를 들어, std::vector
강력한 예외 보장을 희생하지 않고 비 투척 이동 작업을 사용할 수 있습니다. 그렇지 않으면 (C ++ 98에서와 같이) 복사 요소로 폴백해야합니다.
이러한 종류의 최적화는 알고리즘 수준에 있으며 컴파일러 최적화에 의존하지 않습니다. 특히 요소를 복사하는 데 비용이 많이 드는 경우 큰 영향을 줄 수 있습니다.
- noexcept를 사용한 후 성능 향상을 현실적으로 볼 수있는 시점은 언제입니까? 특히, noexcept를 추가 한 후 C ++ 컴파일러가 더 나은 기계 코드를 생성 할 수있는 코드의 예를 제공하십시오.
noexcept
예외 사양을 사용하지 않거나 throw()
스택을 풀 때 표준에 따라 컴파일러에서 더 많은 자유를 얻을 수 있다는 이점이 있습니다. 이 throw()
경우 에도 컴파일러는 스택을 완전히 풀어야합니다 (그리고 객체 구성의 정확한 역순으로해야합니다).
에서 noexcept
경우에, 다른 한편으로는 그렇게 할 필요가 없습니다. 스택을 풀어야 할 필요는 없습니다 (그러나 컴파일러는 여전히 그렇게 할 수 있습니다). 이러한 자유로 인해 스택을 항상 풀 수있는 오버 헤드가 줄어들 기 때문에 코드 최적화가 더욱 강화됩니다.
noexcept, 스택 해제 및 성능 에 대한 관련 질문은 스택 해제가 필요한 경우 오버 헤드에 대한 자세한 정보를 제공합니다.
자세한 내용은 Scott Meyers의 "Effective Modern C ++"책, "항목 14 : 예외가 발생하지 않는 경우를 제외하고 함수 선언"을 참조하십시오.
move_if_nothrow
noccept 이동 ctor가있는 경우 (또는 whatchamacallit) 코드를 사용 하면 성능이 향상됩니다.