프로그래밍 언어/C++

C++ SFINAE 여러 타입에 대응하는 템플릿 오버로딩

ShovelingLife 2022. 6. 10. 09:30
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
 
using namespace std;
 
template <bool B, typename T = void>
using enable_if_t = typename enable_if<B, T>::type;
 
template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
void Run(T& t) 
{
    // 정수 타입들을 받는 함수 (int, char, unsigned, etc.)
    cout << "\n정수 타입들을 받는 함수" << endl;
    cout << " 값 : " << t << endl;
}
 
template <typename T, std::enable_if_t<std::is_pointer<T>::value>* = nullptr>
void Run(T& t)
{
    // 정수 포인터 타입들을 받는 함수 (int, char, unsigned, etc.)
    cout << "\n정수 포인터 타입들을 받는 함수" << endl;
    
    for (int i = 0; i < sizeof(t); i++)
        cout << "값 : " << t[i] << endl;
}
 
template <typename T, std::enable_if_t<std::is_class<T>::value>* = nullptr>
void Run(T& t) 
{
    // 일반적인 클래스들을 받는 함수
    cout << "\n일반적인 클래스들을 받는 함수" << endl;
 
    for (int i = 0; i < t.size(); i++)
        cout << "값 : " << t[i] << endl;
}
 
int main()
{
    vector<int> test_vec;
    int*        test_arr = new int[10];
    int         val = 10;
 
    for (int i = 0; i < 10; i++)
    {
        test_arr[i] = i + 1;
        test_vec.push_back(i + 1);
    }
    Run(val);
    Run(test_arr);
    Run(test_vec);
    delete[] test_arr;
    return 0;
}

결과

두번째 방법

#include <iostream>
#include <functional>
 
using namespace std;
 
template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
 
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void Run(T& t)
{
    cout << t << endl;
}
 
int main()
{
    int val = 10;
    Run(val);
}