Menu
Coddy logo textTech

템플릿 특수화

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 66번째.

때로는 모든 타입에 일반 템플릿이 잘 작동하지 않습니다. 예를 들어, >를 사용하여 C 스타일 문자열을 비교하면 실제 텍스트가 아니라 포인터 주소를 비교합니다. 템플릿 특수화를 사용하면 특정 타입에 맞는 사용자 지정 구현을 제공하면서 다른 모든 경우에는 일반 버전을 유지할 수 있습니다.

전체 특수화는 하나의 특정 타입에 대한 전체 템플릿을 대체합니다. 빈 템플릿 매개변수 목록으로 선언하고 구체적인 타입을 지정합니다:

// 기본 템플릿
template <typename T>
class Printer {
public:
    void print(T value) {
        std::cout << value << std::endl;
    }
};

// const char*에 대한 완전 특수화
template <>
class Printer<const char*> {
public:
    void print(const char* value) {
        std::cout << "String: " << value << std::endl;
    }
};

Printer<int> intPrinter;
intPrinter.print(42);           // 출력: 42

Printer<const char*> strPrinter;
strPrinter.print("hello");      // 출력: String: hello

Function 템플릿은 특수화할 수도 있습니다:

template <typename T>
bool isEqual(T a, T b) {
    return a == b;
}

template <>
bool isEqual<const char*>(const char* a, const char* b) {
    return std::strcmp(a, b) == 0;
}

isEqual(5, 5);              // 일반 버전을 사용합니다
isEqual("hi", "hi");        // 특수화된 버전을 사용합니다

컴파일러는 항상 가장 구체적인 일치를 우선합니다. 사용 중인 정확한 타입에 대한 특수화가 존재하면 일반 템플릿보다 해당 특수화가 선택됩니다.

challenge icon

챌린지

쉬움

특정 타입에 맞게 동작을 사용자 지정하면서도 그 외의 모든 타입에 대해 제네릭 대체 동작을 유지할 수 있도록, 템플릿 특수화의 작동 방식을 보여 주는 타입 인식 포매터 시스템을 만들어 보겠습니다.

템플릿 코드를 구성하기 위해 두 개의 파일을 만듭니다:

  • Formatter.h: 표시할 값을 형식화하는 Formatter라는 클래스 템플릿을 Define합니다. 제네릭 템플릿은 모든 타입에서 작동해야 하지만, 사용자 지정 처리가 필요한 타입을 위한 특수화된 버전도 만듭니다.

    Primary Formatter 템플릿에는 다음이 있어야 합니다:

    • 타입 T의 값을 받아 Value: <value>를 출력하는 format() method

    1 또는 0 대신 사람이 읽을 수 있는 텍스트를 출력하도록 bool에 대한 Full 특수화를 만듭니다:

    • Boolean: true 또는 Boolean: false를 출력하는 format() method

    문자열 양쪽에 따옴표를 추가하도록 const char*에 대한 Full 특수화를 만듭니다:

    • String: "<value>"를 출력하는 format() method

    또한 같은 타입의 두 값을 받아 다음과 같이 함께 출력하는 formatPair라는 function template을 만듭니다: Pair: [<first>, <second>]

    각 문자열을 따옴표로 감싸도록 const char*에 대한 formatPair 특수화도 만듭니다: Pair: ["<first>", "<second>"]

  • main.cpp: 네 개의 입력을 읽습니다(각각 별도의 줄에 입력):
    1. 정수
    2. double
    3. 문자열로 입력된 Boolean (true 또는 false)
    4. 문자열 값

    적절한 Formatter 객체를 만들고 각 타입에 대해 format()을 호출하여 포매터를 사용해 봅니다:

    1. Formatter<int>를 사용하여 정수를 형식화
    2. Formatter<double>를 사용하여 double을 형식화
    3. Formatter<bool>를 사용하여 Boolean을 형식화(먼저 문자열 입력을 bool로 Convert)
    4. Formatter<const char*>를 사용하여 문자열을 형식화

    그런 다음 function template 특수화를 사용해 봅니다:

    1. 두 정수 10과 20을 사용하여 formatPair 호출
    2. 두 C-문자열 "hello""world"를 사용하여 formatPair 호출

예를 들어 입력이 42, 3.14, true, Hello인 경우:

Value: 42
Value: 3.14
Boolean: true
String: "Hello"
Pair: [10, 20]
Pair: ["hello", "world"]

제네릭 템플릿은 정수와 double을 동일한 방식으로 처리하는 반면, boolconst char*에 대한 특수화된 버전은 사용자 지정 형식을 제공한다는 점에 주목하세요. 컴파일러는 사용하는 각 타입에 대해 가장 구체적으로 일치하는 항목을 자동으로 선택합니다.

직접 해보기

#include <iostream>
#include <string>
#include "Formatter.h"

using namespace std;

int main() {
    // 입력 읽기
    int intVal;
    double doubleVal;
    string boolStr;
    string strVal;
    
    cin >> intVal;
    cin >> doubleVal;
    cin >> boolStr;
    cin >> strVal;
    
    // 문자열을 bool로 변환
    bool boolVal = (boolStr == "true");
    
    // TODO: Formatter<int>를 생성하고 정수를 포맷하세요
    
    // TODO: Formatter<double>를 생성하고 double을 포맷하세요
    
    // TODO: Formatter<bool>를 생성하고 불리언을 포맷하세요
    
    // TODO: Formatter<const char*>를 생성하고 문자열을 포맷하세요
    // Hint: const char*를 얻으려면 strVal.c_str()를 사용하세요
    
    // TODO: 두 정수 10과 20으로 formatPair를 호출하세요
    
    // TODO: 두 C-문자열 "hello"와 "world"로 formatPair를 호출하세요
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C++ 컴파일러