2016-09-03 3 views
1

나는 이와 같은 코드를 가지고 있습니다 ("우주선"과 같은 연산자).템플릿 함수에서 코드 반복을 정확하게 제거하는 방법

template <class T> 
int comparator(const T &a, const T &b){ 
    if (a < b){ 
     return -1; 
    }else if (a > b){ 
     return +1; 
    } 

    return 0; 
} 

inline int comparator(const char *a, const char *b){ 
    return strcmp(a, b); // I never tried this, included just to get the idea 
} 

inline int comparator(char const a, char const b){ 
    return a - b; 
} 

inline int comparator(int const a, int const b){ 
    return a - b; 
} 

몇 가지 서명 된 유형 (char, short, int, long 등)에 대한 반복을 쉽게 제거 할 수 있습니까? SFINAE를 사용해 보았지만 그 결과는별로 고무적이지 않았습니다. 템플릿 클래스

template <class T> 
int comparator(const T &a, const T &b){ 
    return comparator_impl<T>::comparator(a, b); 
} 

기본 템플릿 클래스 구현 템플릿 기능을 위임하여

+2

후 당신의 테이크 다음은 작업 예입니다. – LogicStuff

+0

난 그것을 corectly 컴파일하지 못했습니다 – Nick

답변

2

: SFINAE이에서

#include<type_traits> 
#include<utility> 
#include<iostream> 

template <class T> 
int comparator_(char, const T &a, const T &b){ 
    std::cout << "catch all" << std::endl; 
    return (a<b)?-1:((a>b)?1:0); 
} 

template<typename T> 
std::enable_if_t<std::is_same<T,int>::value or std::is_same<T,char>::value, int> 
comparator_(int, T const a, T const b){ 
    std::cout << "char or int" << std::endl; 
    return a - b; 
} 

template<typename... A> 
int comparator(A&&... args) { 
    return comparator_(0, std::forward<A>(args)...); 
} 

int main() { 
    comparator(42,0); 
    comparator('c', 'g'); 
    comparator(42u, 0u); 
} 
+1

enable_if 행의 "or"은 올바른 C++입니까? 나는 전에 그것을 본 적이 없다. – SCFrench

+0

compare_()의 첫번째 인자의 이유는 무엇입니까 – Nick

+0

@SCFrench'또는'와'와'는 각각'||'과'&&'를 의미하는 유효한 C++입니다. –

1

시작 당신이 이미 쓴 것입니다 : 이제

template<class T> 
class comparator_impl { 

public: 
    static int comparator(const T &a, const T &b){ 
     if (a < b){ 
      return -1; 
     }else if (a > b){ 
      return +1; 
     } 

    return 0; 
}; 

, 사용되는 별도의 템플릿 클래스가 부호있는 정수 유형의 경우 :

template<class T> 
class signed_int_comparator_impl { 

public: 
    static int comparator(T a, T b) 
    { 
      return a-b; 
    } 
    return 0; 
}; 

이제는 specia 리제 두 번째에서 상속 전문화와 첫 번째 템플릿 클래스 :

template<> 
class comparator_impl<char> : public signed_int_comparator_impl<char> {}; 

template<> 
class comparator_impl<int> : public signed_int_comparator_impl<int> {}; 

비누 거품이 부호있는 정수 유형을 나머지를 위해, 반복, 린스.

comparator_implconst char *으로 전문화하려면 자유롭게하십시오.

1
  1. 템플릿 전문화의 경우 템플릿 기능이 아닌 템플릿 클래스/구조체를 사용하는 것이 좋습니다. http://www.gotw.ca/publications/mill17.htm
  2. std::is_integralstd::is_signed은 SFINAE에 맞는 도구와 같습니다. 다음과 같은 예에서와 같이, 태그 파견 및 템플릿 과부하를 함께 혼합 할 수 https://ideone.com/8wm54h
+0

예를 게시 할 수 있습니다 pls – Nick

+0

예를 들어 –

+0

위대한 매우 명확한 예제를 추가했습니다. 나는 여전히 템플릿 클래스가 가지고있는 것보다 템플릿 함수가 부족하다는 것을 이해하려고 노력한다. – Nick

관련 문제