Type Traits 2
개요
타입 특성(Type Traits)은 컴파일 시간에 타입에 대한 정보를 얻거나 타입을 변환하는 데 사용되는 템플릿 기반의 메커니즘입니다. <type_traits>
헤더에 정의된 클래스 템플릿들을 통해, 특정 타입이 정수형인지, 포인터인지, 혹은 두 타입이 동일한지 등을 확인할 수 있습니다. 이를 활용하면 템플릿 프로그래밍에서 타입에 따른 조건부 컴파일, static_assert
를 이용한 타입 제약, 오버로드 해석 제어(SFINAE) 등을 효과적으로 구현할 수 있습니다.
C++ 버전별 주요 키워드 도입 시기
- C++11:
<type_traits>
헤더와 함께 대부분의 핵심 타입 특성들이 도입되었습니다. (std::is_same
,std::is_integral
,std::enable_if
,std::conditional
등) - C++14: 타입 특성의
::type
멤버에 대한 별칭(alias)으로_t
접미사가 붙은 템플릿들이 추가되었습니다. (예:std::enable_if_t
) - C++17: 타입 특성의
::value
멤버에 대한 별칭으로_v
접미사가 붙은 변수 템플릿들이 추가되었습니다. (예:std::is_same_v
) - C++20:
std::remove_cvref
와 같이 참조 및 const/volatile 한정자를 한 번에 제거하는 등 편의성을 높인 타입 특성들이 추가되었습니다.
내용 설명
타입 특성은 주로 다음과 같은 형태로 정보를 제공합니다.
- 타입 질의(Type Queries):
std::is_integral<T>::value
와 같이bool
타입의static
멤버value
를 통해 타입의 속성을 확인합니다. C++17부터는std::is_integral_v<T>
처럼_v
템플릿을 사용하는 것이 더 간결합니다. - 타입 변환(Type Transformations):
std::remove_reference<T>::type
과 같이type
이라는static
멤버 타입을 통해 기존 타입을 새로운 타입으로 변환합니다. C++14부터는std::remove_reference_t<T>
처럼_t
템플릿을 사용하는 것이 편리합니다.
예제 코드는 is_string
이라는 커스텀 타입 특성을 정의하여 to_upper_case
와 to_lower_case
함수에 전달되는 템플릿 인자가 각각 std::string
과 std::string_view
인지 컴파일 시간에 검증합니다. std::conjunction
은 여러 타입 특성 조건을 논리 AND 연산으로 묶어주는 유틸리티로, 모든 조건이 참일 때 true
가 됩니다.
static_assert
는 컴파일 시간에 주어진 조건이 거짓일 경우 컴파일을 중단시키고 에러 메시지를 출력하는 기능으로, 타입 특성과 함께 사용하면 템플릿의 타입 제약을 명확하게 강제할 수 있습니다.
예제 코드
#include <algorithm>
#include <iostream>
#include <string>
#include <string_view>
#include <type_traits>
template <typename StringType, typename ViewType>
struct is_string
: public std::conjunction<std::is_same<std::string, StringType>,
std::is_same<std::string_view, ViewType>>
{
};
template <typename StringType, typename ViewType>
StringType to_upper_case(ViewType text);
template <typename StringType, typename ViewType>
StringType to_lower_case(ViewType text);
int main()
{
auto input_text = std::string{};
std::cout << "Please enter any text: ";
std::cin >> input_text;
std::cout << "to_upper_case: "
<< to_upper_case<std::string, std::string_view>(input_text)
<< '\n';
std::cout << "to_lower_case: "
<< to_lower_case<std::string, std::string_view>(input_text)
<< '\n';
return 0;
}
template <typename StringType, typename ViewType>
StringType to_upper_case(ViewType text)
{
static_assert(is_string<StringType, ViewType>::value, "The function requires std::string and std::string_view types.");
auto result = StringType{text};
std::transform(result.begin(), result.end(), result.begin(), toupper);
return result;
}
template <typename StringType, typename ViewType>
StringType to_lower_case(ViewType text)
{
static_assert(is_string<StringType, ViewType>::value, "The function requires std::string and std::string_view types.");
auto result = StringType{text};
std::transform(result.begin(), result.end(), result.begin(), tolower);
return result;
}
실행 결과
Please enter any text: HelloWorld
to_upper_case: HELLOWORLD
to_lower_case: HELLOWORLD
활용팁
- 간결한 코드 작성: C++17 이상을 사용한다면
_v
접미사가 붙은 변수 템플릿(예:std::is_same_v<T, U>
)을 사용하여 코드를 더 간결하고 가독성 높게 만들 수 있습니다. - SFINAE 대체: C++11의
std::enable_if
나 SFINAE(Substitution Failure Is Not An Error) 기법 대신 C++17의if constexpr
와 타입 특성을 함께 사용하면, 특정 타입 조건에 따라 다른 코드를 컴파일하도록 더 직관적으로 구현할 수 있습니다. - 개념(Concepts)과 함께 사용: C++20에 도입된 개념(Concepts)은 타입 특성을 기반으로 하여 템플릿 인자에 대한 제약을 훨씬 더 명확하고 간결하게 표현할 수 있게 해줍니다. 타입 특성은 개념을 구성하는 기본 요소로 활용됩니다.
'개발 > C++ (98,03,11,14,17,20,23)' 카테고리의 다른 글
Modern C++ : Variadic Templates and Fold Expressions (11, 17) (0) | 2025.09.26 |
---|---|
Modern C++ : std::concepts (20) (0) | 2025.09.25 |
Modern C++ : Type Traits 1 (11, 14, 17, 20) (0) | 2025.09.24 |
Modern C++ : 템플릿 특수화 (Template Specialization) (98, 11, 17) (0) | 2025.09.23 |
Modern C++ : 복사 및 이동 의미론 (Copy and Move Semantics) (98, 11) (0) | 2025.09.22 |
Modern C++ : 연산자 오버로딩 (Operator Overloading) (98, 11, 20) (0) | 2025.09.21 |
Modern C++ : 클래스 템플릿(Class Template) (98) (0) | 2025.09.20 |
Modern C++ : 다형성(Polymorphism) (98, 11) (0) | 2025.09.19 |