ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION310 / 1500

복사·이동 생성자를 삭제했는데 return T{}가 C++17에서 가능한 이유는 무엇인가요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

C++17의 return T{};가 가능한 이유는 복사·이동 생성자를 최적화로 호출하지 않는다는 뜻보다, 순수 prvalue가 최종 목적지 객체를 직접 초기화하는 언어 모델을 사용하기 때문입니다. 예를 들어 T make() { return T{}; }와 T x = make();에서는 먼저 임시 T를 만들고 다시 x로 옮기는 중간 객체가 필요하지 않습니다. T{}를 만들 수 있는 생성자는 선택·접근 가능해야 하지만, T(const T&) = delete;와 T(T&&) = delete;인 것만으로 이 경로가 거부되지는 않습니다.

다만 소멸자까지 불필요한 것은 아닙니다. 반환 결과는 언젠가 파괴되어야 하므로 소멸자가 접근 가능하고 삭제되지 않아야 합니다. 반대로 T local; return local;은 NRVO가 선택 사항이라 생략되지 않은 경로의 복사 또는 암시적 이동 생성자가 필요할 수 있고, return std::move(local);은 이동을 직접 요구합니다. 따라서 “C++17부터 모든 return에서 copy elision이 보장된다”가 아니라 “같은 타입의 prvalue가 목적지를 직접 초기화하는 특정 경로에서 이동·복사 호출이 언어상 필요 없다”고 답하겠습니다.

예상 상태는 T{} 생성 → 반환 목적지에 직접 구성 → 호출자에서 x 파괴입니다. 이 환경에서는 C++ 코드를 실행한 측정이 아니라 규칙을 기준으로 설명하며, 실제 확인은 -std=c++17과 소멸자 접근성, 반환 타입 변환 여부를 함께 고정해야 합니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • return T{};를 중간 임시에서 결과 객체로 옮기는 선택적 최적화가 아니라 C++17 prvalue의 직접 목적지 구성으로 설명합니다.
  • 이동·복사 생성자를 삭제해도 선택한 기본 생성자와 결과 객체의 접근 가능한 소멸자는 여전히 필요하다는 컴파일 경계를 제시합니다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 이름 있는 지역 반환의 NRVO까지 C++17에서 항상 보장된다고 말하면 안 됩니다.
  • 소멸자를 private으로 만들어도 실제 임시가 없다며 항상 컴파일된다고 단정하면 안 됩니다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

  • 같은 타입의 직접 prvalue 반환과 변환 생성자를 거치는 반환을 C++17 컴파일 행렬로 비교하면 어떤 차이가 드러날까요?
  • return local;에서 삭제된 복사·이동 생성자가 NRVO 선택 여부에 따라 왜 별도로 문제가 되는지 추적해 보세요.

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

← 전체 질문 보기