SFINAE(Substitution Failure Is Not An Error)는 템플릿 메타프로그래밍에서 중요한 개념으로, 템플릿 인자 치환 실패가 오류를 일으키지 않도록 하는 원리입니다. 이를 통해 조건부로 템플릿을 선택할 수 있습니다. 오늘은 SFINAE와 함께 개념(Concepts)에 대해 학습하겠습니다.
SFINAE
SFINAE란?
SFINAE는 "Substitution Failure Is Not An Error"의 약자로, 템플릿 인자 치환이 실패하더라도 이를 오류로 간주하지 않고, 다른 템플릿이 선택될 수 있도록 합니다. 이를 통해 템플릿 특수화나 함수 오버로딩 시 특정 조건에 따라 선택할 수 있습니다.
SFINAE의 기본 사용법
다음은 SFINAE를 사용하여 특정 타입에 대해서만 템플릿을 활성화하는 예제입니다.
#include <iostream>
#include <type_traits>
// 기본 템플릿
template <typename T>
void func(T) {
std::cout << "General template" << std::endl;
}
// 특수화 템플릿 - 정수 타입에 대해서만 활성화
template <typename T>
typename std::enable_if<std::is_integral<T>::value>::type func(T) {
std::cout << "Integral type specialization" << std::endl;
}
int main() {
func(10); // Integral type specialization
func(3.14); // General template
func("Hello"); // General template
return 0;
}
이 예제에서 std::enable_if
와 std::is_integral
을 사용하여 템플릿이 정수 타입일 때만 특수화되도록 합니다.
std::enable_if와 함께 사용하는 타입 traits
std::is_integral<T>
: T가 정수 타입인지 확인std::is_floating_point<T>
: T가 부동 소수점 타입인지 확인std::is_pointer<T>
: T가 포인터 타입인지 확인
이러한 타입 traits를 사용하여 템플릿의 특수화 및 오버로딩을 컨트롤할 수 있습니다.
Concepts (개념)
Concepts란?
Concepts는 C++20에서 도입된 기능으로, 템플릿 인자의 요구 사항을 명확하게 표현할 수 있습니다. Concepts는 템플릿 메타프로그래밍을 더 간단하고 읽기 쉽게 만들어 줍니다.
Concepts의 기본 사용법
Concepts를 사용하여 템플릿 인자의 제약 조건을 정의할 수 있습니다. 예를 들어, 정수 타입에만 작동하는 함수를 정의할 수 있습니다.
#include <iostream>
#include <concepts>
// 정수 타입에 대해서만 작동하는 Concept 정의
template <typename T>
concept Integral = std::is_integral_v<T>;
// Integral 타입에 대해서만 작동하는 함수
template <Integral T>
void func(T) {
std::cout << "Integral type function" << std::endl;
}
int main() {
func(10); // Integral type function
// func(3.14); // 컴파일 오류
// func("Hello"); // 컴파일 오류
return 0;
}
이 예제에서 Integral
이라는 Concept를 정의하고, 이를 템플릿 함수 func
의 제약 조건으로 사용합니다.
기본 제공 Concepts
C++20에서는 다양한 기본 제공 Concepts를 제공합니다:
std::integral<T>
: T가 정수 타입인지 확인std::floating_point<T>
: T가 부동 소수점 타입인지 확인std::convertible_to<T, U>
: T가 U로 변환 가능한지 확인
실습 문제
문제 1: SFINAE를 사용하여 정수 타입에만 작동하는 함수 작성
SFINAE를 사용하여 정수 타입에만 작동하는 템플릿 함수를 작성하세요.
해설:
#include <iostream>
#include <type_traits>
// 기본 템플릿
template <typename T>
void check(T) {
std::cout << "General template" << std::endl;
}
// 특수화 템플릿 - 정수 타입에 대해서만 활성화
template <typename T>
typename std::enable_if<std::is_integral<T>::value>::type check(T) {
std::cout << "Integral type specialization" << std::endl;
}
int main() {
check(10); // Integral type specialization
check(3.14); // General template
check("Hello"); // General template
return 0;
}
문제 2: Concepts를 사용하여 부동 소수점 타입에만 작동하는 함수 작성
Concepts를 사용하여 부동 소수점 타입에만 작동하는 템플릿 함수를 작성하세요.
해설:
#include <iostream>
#include <concepts>
// 부동 소수점 타입에 대해서만 작동하는 Concept 정의
template <typename T>
concept FloatingPoint = std::is_floating_point_v<T>;
// FloatingPoint 타입에 대해서만 작동하는 함수
template <FloatingPoint T>
void check(T) {
std::cout << "Floating point type function" << std::endl;
}
int main() {
// check(10); // 컴파일 오류
check(3.14); // Floating point type function
// check("Hello"); // 컴파일 오류
return 0;
}
이제 3일차의 학습을 마쳤습니다. SFINAE와 Concepts에 대해 상세히 학습하고 실습 문제를 풀어보았습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "C++20의 개념과 모듈"에 대해 다루겠습니다.
'-----ETC----- > C++ 고급 프로그래밍과 응용 프로젝트 시리즈' 카테고리의 다른 글
[C++ 고급 프로그래밍과 응용 프로젝트 시리즈] Day 5: 범위 기반 for 루프와 초기화 리스트 (0) | 2024.08.01 |
---|---|
[C++ 고급 프로그래밍과 응용 프로젝트 시리즈] Day 6: constexpr과 상수 표현식 (0) | 2024.08.01 |
[C++ 고급 프로그래밍과 응용 프로젝트 시리즈] Day 4: C++20의 개념과 모듈 (0) | 2024.08.01 |
[C++ 고급 프로그래밍과 응용 프로젝트] Day 2: 고급 템플릿 프로그래밍 (0) | 2024.08.01 |
[C++ 고급 프로그래밍과 응용 프로젝트] Day 1: 람다 함수와 함수 객체 (0) | 2024.08.01 |