template 형식 연역

2022. 12. 29. 20:46Effective modern C++

3가지 경우 

1. 보편참조가 아닌 참조,포인터인 경우

2.보편참조인 경우

3.포인터도 참조도 아닌 경우

 

 

1. 보편참조가 아닌 참조,포인터인 경우

  • expr 이 참조이면 참조 무시한다.
  • 패턴 부합 방식으로 T 형식 결정

template<typename T>

void func(ParamType& data);

func(expr);

*T&에 const 넘겨도 안전한 이유 const 가 붙으면 이 객체를 매개변수에 전달하는 호출자는 변수가 수정되지 않음을 기대하기 때문에 T에 대해 연역된 형식의 일부가 된다. 

* const 참조인 경우 

param이 const 에 대한 참조로 간주, const 가 T의 일부로 연역될 필요가 X

2.보편참조인 경우

  • 왼쪽값 = T와 ParamType 모두 왼쪽값&가 된다.
  • 오른쪽값 = 1번의 규칙에 따른다.

template <typename T>

void func(T&& param);

func(expr);

 

3.포인터도 참조도 아닌 경우

=값으로 전달 

 

  • expr 이 참조형식이면 참조 무시
  • expr const , volatile 무시

template <typename T>

void func(T param);

func(expr)

 

어차피 복사본이기 때문에 const , volatile 성질을 무시하고 값 복사가 일어난다.

** 값 전달 매개변수에 한해서만 const ,volatile 이 무시되는것

 

* const pointer 인 경우

즉 기존 ptr 에서는 연결된 주소를 변경 할 수 없다.  *ptr의 데이터의 const 와 ptr 자체의 const 를 보장.

하지만 값으로 넘어가는 과정에서 복사가 일어나며 ptr을 복사해서 넘긴다.

이 과정에서 생긴 복사본은 const 성질이 없어지며 포인터에 대한 const 성질은 없음.

 

배열 인수 

배열은 매개변수로 넘길때 포인터로 연역되는 붕괴 현상이 일어난다.

하지만 배열에 대한 참조로 받는 경우 배열 형식 + 배열의 크기로 연역된다.

 

const char [13] data ;

template<typename T>

void f(T& param);

f(data);

 

=> void f(T (&) [13])

출력 : 13

매개변수에 이름을 붙이지 않은 이유는 필요한것이 배열의 크기만 이기 때문이다.

 

함수 인수 

함수 형식도 함수 포인터로 붕괴