반응형

Member Detect IDioms

  • 클래스의 멤버 타입 존재 여부 확인

  • 클래스의 멤버 함수 존재 여부 확인

//컴파일 타임의 함수 시그니처에 대한 특성만 활용하는 특성을 이용하는 기법

// 함수 시그니처만 사용함으로 구현부가 없어도 괜찮음
char foo(int a);
short foo(double d);

int main()
{
    int n = 10;

    cout << sizeof(n) << endl; // 4
    //cout << sizeof(foo) << endl; // Error
    cout << sizeof(foo(3)) << endl; // 1
    cout << sizeof(foo(3.3)) << endl; // 2
}
#include <iostream>
#include <vector>
using namespace std;

// 멤버 타입을 가진 데이터용 템플릿(반환값이 char로 1바이트)
template<typename T> 
char check(typename T::value_type* a);

// 멤버 타입이 없는 데이터용 템플릿(반환값이 short로 2바이트)
template<typename T>
short check(...);

// 멤버 타입이 없는 데이터
struct NoValueType
{
};
// 멤버 타입이 있는 데이터
struct HasValueType
{
    typedef int value_type;
};

// 멤버 타입 존재를 여부 확인 함수
template<typename T>
struct has_value_type
{
    // 반환값이 char(1바이트)일때는 true, short(2바이트)일때는 false
    static constexpr bool value = (sizeof(check<T>(0)) == 1); 
};

int main()
{
    cout << has_value_type<HasValueType>::value << endl;
    cout << has_value_type<NoValueType>::value << endl;

    HasValueType t1;
    cout << sizeof(check<HasValueType>(0)) << endl;
    NoValueType t2;
    cout << sizeof(check<NoValueType>(0)) << endl;
}
#include <iostream>
#include <vector>
using namespace std;

// 멤버함수가 존재할 경우 
template<typename T> 
char check(decltype(T().resize(0))* a);

// 멤버함수가 존재하지 않을 경우
template<typename T>
short check(...);

// 멤버함수 존재 체크
template<typename T>
struct has_resize
{
    static constexpr bool value = (sizeof(check<T>(0)) == 1); 
};

int main()
{
    // vector는 resize가 있으므로 true 리턴
    cout << has_resize<vector<int>>::value << endl;
    
    // array는 resize가 없으므로 false 리턴
    cout << has_resize<array<int, 10>>::value << endl;
}
반응형

반응형
  • C++17 이전까지는 클래스 템플릿은 함수 인자를 통해 타입을 추론 할 수 없기 때문에, 클래스 템플릿 사용이 복잡하고 불편함
  • "클래스 템플릿의 객체를 생성하는 함수 템플릿"을 사용
    • 함수 템플릿은 함수 인자를 통해서 컴파일러가 추론(Argument Type Deduction)할 수 있는 특징 활용 기법
  • make_pair(), make_tuple()등의 make 계열 함수, STL 삽입반복자등
#include <iostream>

template<typename T> void foo(T a) {}
template<typename T, typename U> struct pair
{
    T first;
    U second;
    pair(const T& a, const U& b) : first(a), second(b) {}
};

template<typename T, typename U>
pair<T, U> make_pair(const T& a, const U& b)
{
    return pair<T, U>(a, b);
}

int main()
{
    pair<int, double> p(1, 3.4);
    foo(p);
    foo(pair<int, double>(1, 3.4)); // 클래스 템플릿은 꼭 타입 전달 필요
    foo(make_pair(1, 3.4)); // 함수 템플릿으로 타입 추론하여 클래스 객체 생성
}
반응형

+ Recent posts