본문 바로가기
-----ETC-----/C++ 고급 프로그래밍과 응용 프로젝트 시리즈

[C++ 고급 프로그래밍과 응용 프로젝트] Day 3: SFINAE와 개념

by cogito21_cpp 2024. 8. 1.
반응형

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_ifstd::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의 개념과 모듈"에 대해 다루겠습니다.

반응형