c++ 적절한 복사 및 스왑 이디엄을 사용하는 대입 연산자에서 noexcept를 사용하는 방법은 무엇입니까?




연산자 오버로딩+ (2)

이동 할당 연산자는 noexcept (STL 컨테이너에 유형을 저장하는 등)로 선언해야합니다. 그러나 copy-and-swap 관용구는 복사 및 이동 할당 연산자를 단일 코드로 정의 할 수 있습니다. 이 경우 noexcept 지정자로 수행 할 작업은 무엇입니까? 복사본 구성이 실패 할 수는 있지만 noexcept 지정자를 위반할 수 있는지 여부는 의심 스럽습니다.

// Is it correct considering that T copy constructor can throw?
T& operator=(T other) noexcept;

평소대로 는 correct . 내가 원하는 것은 그 요점을 보여주는 코드 조각을 보여주는 것입니다.

#include <iostream>

struct foo {

    foo() = default;

    foo(const foo&) {
        std::cout << "throw\n";
        throw 1;
    }

    foo& operator =(foo) noexcept {
        return *this;
    }
};

int main() {

    foo f, g;
    try {
        f = g; // throws
    }
    catch(int) {
        std::cout << "catch\n";
    }
}

gcc 4.8.1 ( -std=c++11 -Wall -Wextra -pedantic )으로 컴파일하면 아무 경고도 표시되지 않습니다. 코드를 실행하면 다음과 같은 결과가 출력됩니다.

throw
catch

따라서 복사 생성자는 호출 될 때 throw하지만 operator =() 내부에서는 고려되지 않으므로 noexcept 약속이 수행되었습니다. 그렇지 않으면, catch 인쇄하기 전에 terminate가 호출됩니다.


복사본은 호출자의 호출 에서 만들어 지므로 함수가 수행하는 작업의 일부가 아닙니다. 따라서 함수에 의해 제어 될 수 없으므로 noexcept 스펙에이 정보를 포함 할 수 없습니다.

당신이 할 수있는 유일한 일은 그것을 안전하게 플레이하고 noexcept 명세에 옵션을 추가하는 것입니다. 물론, 그것은 당신이 약간의 가사를 얻는다는 것을 의미합니다.







copy-and-swap