이 글에서는 C++ STL의 std::is_reference 템플릿이 어떻게 동작하는지, 그 문법과 실제 사용 예제를 자세히 살펴보겠습니다.
is_reference는 <type_traits> 헤더 파일에 포함된 템플릿으로, 주어진 타입 T가 참조(reference) 타입인지 아닌지를 확인하는 데 사용됩니다.
이 템플릿은 is_rvalue_reference와 is_lvalue_reference의 조합으로 볼 수 있습니다. 두 검사 중 하나라도 참(true)이라면 is_reference의 결과도 참이 됩니다.
C++에서 참조(Reference)란 무엇인가?
참조는 이미 존재하는 변수에 대한 별칭(alias), 즉 다른 이름입니다. 참조는 포인터와 다음과 같은 점에서 차이가 있습니다.
- 참조는 null로 설정할 수 없지만, 포인터는 널 포인터(null pointer)가 될 수 있습니다.
- 참조는 한 번 객체로 초기화되면 다른 객체를 가리키도록 변경할 수 없습니다. 반면 포인터는 언제든지 다른 객체를 가리키도록 변경할 수 있습니다.
- 참조는 생성 시점에 반드시 초기화해야 하지만, 포인터는 생성한 후 나중에 초기화해도 됩니다.
참조는 참조하려는 변수 앞에 앰퍼샌드(&) 기호를 붙여 선언합니다.
문법(Syntax)
template <class T> is_reference;
매개변수(Parameters)
이 템플릿은 타입 T 하나만을 매개변수로 받으며, 해당 타입이 참조 타입인지 여부를 검사합니다.
반환 값(Return Value)
불리언(Boolean) 값을 반환합니다. 주어진 타입이 참조 타입이면 true, 참조 타입이 아니면 false를 반환합니다.
간단한 예제
입력: is_reference<int>::value; 출력: false 입력: is_reference<int&>::value; 출력: true
예제 1: 클래스 타입 검사하기
#include <iostream>
#include <type_traits>
using namespace std;
class TP {
};
int main() {
cout << boolalpha;
cout << "Checking for is_reference: ";
cout << "\n class TP : " << is_reference<TP>::value;
cout << "\n class TP& : " << is_reference<TP&>::value;
cout << "\n class TP&& : " << is_reference<TP&&>::value;
return 0;
}출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
Checking for is_reference: class TP : false class TP& : true class TP&& : true
클래스 자체는 참조 타입이 아니므로 false가 출력되고, 좌측값 참조(TP&)와 우측값 참조(TP&&)는 모두 참조 타입이므로 true가 출력됩니다.
예제 2: 다양한 기본 타입 검사하기
#include <iostream>
#include <type_traits>
using namespace std;
int main() {
cout << boolalpha;
cout << "Checking for is_reference: ";
// int
cout << "\n int: " << is_reference<int>::value;
cout << "\n int&: " << is_reference<int&>::value;
cout << "\n int&&: " << is_reference<int&&>::value;
// char
cout << "\n char: " << is_reference<char>::value;
cout << "\n char&: " << is_reference<char&>::value;
cout << "\n char&&: " << is_reference<char&&>::value;
// float
cout << "\n float: " << is_reference<float>::value;
cout << "\n float&: " << is_reference<float&>::value;
cout << "\n float&&: " << is_reference<float&&>::value;
// double
cout << "\n double: " << is_reference<double>::value;
cout << "\n double&: " << is_reference<double&>::value;
cout << "\n double&&: " << is_reference<double&&>::value;
return 0;
}출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
Checking for is_reference: int: false int&: true int&&: true char: false char&: true char&&: true float: false float&: true float&&: true double: false double&: true double&&: true
정리
std::is_reference는 컴파일 시점에 타입이 참조형인지 판별할 수 있게 해주는 유용한 타입 특성(type trait)입니다. 일반 타입은 false를 반환하고, 좌측값 참조(T&)나 우측값 참조(T&&)는 true를 반환한다는 규칙만 기억하면 됩니다. 이러한 타입 특성은 템플릿 메타프로그래밍에서 오버로딩 분기나 SFINAE 기법을 구현할 때 특히 유용하게 활용됩니다.