int* intPtr{nullptr};
int*& ptrRef{intPtr};
ptrRef = new int;
*ptrRef = 5;
//int& & 불가능.
//int&* 불가능.
개발자의 관점에서 볼 때 객체를 직접 리턴하지 않고 함수 내부에서 원본 객체를 직접 수정하는 방식으로 처리하면 복제로 인한 성능 저하를 줄일 수 있어서 바람직하다고 생각하기 쉽다. 하지만 컴파일러는 이미 예전부터 이렇게 불필요한 복제 작업을 제거해왔다.
(중략)
전달할 객체를 함수 안에서 수정해야 할 때는 비 const 레퍼런스로 전달한다. 단, 9장에서 소개하는 이동 의미론을 이용한다면 객체를 값으로 전달해도 효율적으로 처리된다.
return object;와 같이 작성하면 object가 로컬 변수거나, 함수에 대한 매개변수거나, 임싯값일 때 리턴값 최적화(RVO)가 적용된다. 또한 object가 로컬 변수라면 이름 있는 리턴값 최적화(NRVO)도 적용된다. RVO와 NRVO 둘 다 복제 생략의 한 종류로서, 함수에서 객체를 리턴하는 과정을 굉장히 효율적으로 처리해준다. 복제 생략을 사용하면 컴파일러는 함수에서 리턴하는 객체를 복사하지 않는다. 이를 통해 복제 없는 값 전달 방식을 구현한다. (145p)
#include <iostream>
#include <stdexcept>
using namespace std;
int getInt(int number)
{
if (number == 2)
{
throw invalid_argument("Number cannot be 2.");
}
return number;
}
int main()
{
try
{
cout << getInt(1) << endl;
cout << getInt(2) << endl;
cout << getInt(3) << endl;
}
catch (const invalid_argument& exception)
{
cout << "Exception caught: " << exception.what() << endl;
//cout << "Exception caught: {} ", exception.what() << endl;
}
}
// 출력.
// 1
// Exception caught : Number cannot be 2.
auto[]{}// const int* 라고 생각하겠지만 int* const다.
const auto p1{&i};
auto const p2{&i};
// const int*다.
const auto* p3{&i};
// int* const다.
auto* const p4{&i};
int a {123};
decltype(a) b {456}; // 컴파일러는 b의 타입이 a의 타입인 int라고 추론한다.
decltype(foo()) f2{foo()};