C++ 초급 - 9. 템플릿 기초 (3 - C++17의 template<typename T> auto)

2025. 2. 22. 17:09프로그래밍 언어/C++

📌 9.3 C++17의 template<typename T> auto

C++17부터 템플릿 함수에서 auto를 반환 타입으로 설정할 수 있어 반환값의 타입을 더욱 유연하게 지정할 수 있다.
이를 통해 코드 가독성이 향상되고, 더욱 강력한 타입 추론이 가능해진다.


📌 1. template<typename T> auto의 기본 개념

🔹 (1) auto를 사용한 반환 타입 추론

  • C++17 이전에는 템플릿 함수에서 반환 타입을 명확하게 지정해야 했음.
  • C++17부터 auto를 사용하면 반환 타입을 자동으로 추론 가능.

💡 기본 문법

template<typename T>
auto 함수이름(T 매개변수) {
    return 값;
}

💡 예제: auto를 활용한 반환 타입 자동 추론

#include <iostream>

template<typename T>
auto square(T x) {
    return x * x;  // 컴파일러가 반환 타입을 자동 추론
}

int main() {
    std::cout << square(4) << std::endl;   // int -> 16
    std::cout << square(4.5) << std::endl; // double -> 20.25
    return 0;
}

🔹 출력 결과

16
20.25

💡 설명

  • auto를 반환 타입으로 설정하면, 컴파일러가 반환값의 타입을 자동으로 추론.
  • square(4)는 int를 반환, square(4.5)는 double을 반환.

📌 2. 반환 타입 자동 추론 (decltype(auto)와의 차이점

🔹 (1) auto와 decltype(auto)의 차이점

반환 타입 특징
auto 표현식의 값을 기반으로 타입을 추론
decltype(auto) 표현식의 타입을 유지하며 추론

💡 예제: auto vs decltype(auto)

#include <iostream>

int x = 10;

template<typename T>
auto getValue(T& var) { return var; }  // 값 복사 (auto)

template<typename T>
decltype(auto) getReference(T& var) { return var; }  // 참조 유지 (decltype(auto))

int main() {
    std::cout << getValue(x) << std::endl;  // x의 값을 복사하여 반환
    std::cout << getReference(x) << std::endl;  // x의 참조를 유지
    return 0;
}

💡 설명

  • auto는 값을 복사하여 반환.
  • decltype(auto)는 변수의 원래 타입을 유지하여 반환 (참조 여부 포함).

📌 3. 템플릿 함수에서 auto를 사용하여 타입 유추하기

🔹 (1) auto의 장점

  • 템플릿의 가독성을 향상시킴.
  • 컴파일러가 적절한 타입을 자동으로 추론.

💡 예제: auto를 활용한 템플릿 함수

#include <iostream>

// 템플릿을 사용하여 두 값의 합을 반환
template<typename T1, typename T2>
auto add(T1 a, T2 b) {
    return a + b;  // 컴파일러가 반환 타입을 자동 추론
}

int main() {
    std::cout << add(3, 4.5) << std::endl;  // int + double = double (7.5)
    return 0;
}

🔹 출력 결과

7.5

💡 설명

  • add(3, 4.5) 호출 시 int + double이므로 반환 타입은 double로 추론됨.

📌 4. 람다(Lambda)와 auto를 활용한 템플릿 프로그래밍

🔹 (1) auto를 사용하여 람다 반환 타입 유추

  • C++14부터 람다에서 auto 반환 타입을 사용할 수 있음.
  • C++17에서는 템플릿과 조합하여 더욱 강력한 추론이 가능.

💡 예제: 람다와 auto 활용

#include <iostream>
#include <functional>

// 람다를 반환하는 템플릿 함수
template<typename T>
auto createLambda(T x) {
    return [x](T y) { return x + y; };  // 람다 반환
}

int main() {
    auto lambda = createLambda(10);  // 람다 객체 생성
    std::cout << lambda(5) << std::endl;  // 10 + 5 = 15
    return 0;
}

🔹 출력 결과

15

💡 설명

  • createLambda(10) → 람다 [x](T y) { return x + y; }가 반환됨.
  • 템플릿을 활용하여 다양한 타입의 람다를 생성 가능.

📌 5. C++17 이전 방식과 비교 (decltype, trailing return type)

🔹 (1) 기존 방식 (C++11 이전)

  • C++11 이전에는 auto를 사용할 수 없어 decltype이나 trailing return type을 사용해야 했음.

💡 예제: decltype을 활용한 반환 타입 지정

template<typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>()) add(T1 a, T2 b) {
    return a + b;
}

💡 예제: trailing return type을 활용한 반환 타입 지정

template<typename T1, typename T2>
auto add(T1 a, T2 b) -> decltype(a + b) {
    return a + b;
}

💡 C++17 이후 auto 활용 (더 간결한 코드)

template<typename T1, typename T2>
auto add(T1 a, T2 b) {
    return a + b;
}

🔹 C++17 이후 auto를 사용하면 코드가 훨씬 간결해짐.


📌 6. 정리

개념  설명
C++17 template<typename T> auto 반환 타입을 자동 추론하여 유연한 코드 작성 가능
auto와 decltype(auto) 차이점 auto는 값 복사, decltype(auto)는 원래 타입 유지
템플릿 함수에서 auto 활용 반환 타입을 명시하지 않고 자동으로 추론 가능
람다와 auto 조합 auto를 사용하여 람다의 반환 타입도 추론 가능
C++17 이전 방식과 비교 decltype과 trailing return type보다 간결한 코드 작성 가능