2016-09-27 1 views
1

TL; DR : 템플릿 인수의 형식에 따라 조건부 typedef를 수행하려면 어떻게해야합니까?일반 래퍼 쓰기 : 템플릿 인수와 다른 형식을 단일 클래스 내부 형식에 조건부로 매핑

다른 비트 셋 구현을위한 래퍼를 쓰고 있습니다. 그 때문에 나는 std::bitset<>boost::dynamic_bitset<>을 참조하고있다. 나는 boost::dynamic_bitset<>std::bitset<>의 구현을 따르는 것을 관찰하고, 예를 들어 에 의해 반환 된 인덱스 처리를위한 프록시 클래스를 호출하면, std::bitset<>처럼 reference 클래스가된다. 비트 세트 형 BITSET와 템플릿입니다 - - 그래서, 그 때문에 내 래퍼에 유용 그때

typename BITSET::reference operator[](INDEX_TYPE i) 
    { return bitset[i]; } 

을 할 수 있으며, 그것은 모두 std::bitset<>boost::dynamic_bitset<>을 위해 작동합니다.

그러나 이와 같이 병렬화되지 않은 기능이 있습니다. 예를 들어 같이 인덱스 유형으로 boost::dynamic_bitset<>typedef std::size_t size_type;를 선언

bool operator[](size_type pos) const { return test(pos); }

그러나 std::bitset<>은 단순히위한 size_t 사용

_GLIBCXX_CONSTEXPR bool                   
operator[](size_t __position) const 
{ return _Unchecked_test(__position); } 

그래서, 내 래퍼 내가 그런 typedef size_t INDEX_TYPE 또는 뭔가를 할 수 ,이 두 가지가 우연히 (또는하지 않고) 수행하므로 size_t을 사용하지 않는 다른 구현에서는 작동하지 않을 수 있습니다.

은 물론이 작업을 수행 할 정말 일반적인 방법이 없다,하지만 난 적어도 어떻게 든 조건이 유사한 내 INDEX_TYPE을 정의 할 수 있습니다 :

template <class BITSET, class T> 
/** 
* 
* @tparam T Use this parameter to pass on the template parameter that 
*   was used to template BITSET 
*/ 
class BitsetWrapper 
{ 
public: // typedefs 
    if (typeid(BITSET) == bool::dynamic_bitset<T>) 
     typedef tyeanme BITSET::size_type INDEX_TYPE; 
    else if (typeid(BITSET) == std::bitset<T>) 
     typedef size_t INDEX_TYPE; 
    else if (typeid(BITSET) == BitSet<T>) // my own implementation 
     typedef BITSET::INDEX_TYPE INDEX_TYPE; 
    else 
     throw std::invalid_argument("unsupported type: "+typeid(BITSET).name()); 

위의 방법이 작동하지 않는 그것은 한 경우에도 매우 보인다 투박한.

그것은 내 질문의 요점 외에이지만, 단지 완전성이 오류입니다 : 당신은 단지 기능의 외부 클래스 공간에 무작위로 조건문을 넣을 수 없습니다 생각

bitsetWrapper.hpp:34:5: error: expected member name or ';' after declaration specifiers 
    if (typeid(BITSET) == bool::dynamic_bitset<T>) 
    ^
bitsetWrapper.hpp:36:5: error: expected member name or ';' after declaration specifiers 
    else if (typeid(BITSET) == std::bitset<T>) 
    ^
bitsetWrapper.hpp:38:5: error: expected member name or ';' after declaration specifiers 
    else if (typeid(BITSET) == BitSet<T>) 
    ^
bitsetWrapper.hpp:40:5: error: expected member name or ';' after declaration specifiers 
    else 

,이이었다 이상한 상황 때문에 내가 이것을 처음 시도한 때.

그러나 어떻게이 문제에 올바르게 접근 할 수 있습니까?

답변

2

if/else 로직을 사용하여 typedef을 정의 할 수 없습니다. 도우미 클래스를 사용하여 추론 할 수 있습니다. 다음

template <typename T> struct TypedefSelector; 

template <typename T> struct TypedefSelector<boost::dynamic_bitset<T>> 
{ 
    using IndexType = BITSET::size_type; 
}; 

template <typename T> struct TypedefSelector<std::bitset<T>> 
{ 
    using IndexType = size_t; 
}; 

template <typename T> struct TypedefSelector<BitSet<T>> 
{ 
    using IndexType = BITSET::INDEX_TYPE; 
}; 

그리고

사용하십시오 TypedefSelector이없는 typenames를 들어

template <class BITSET, class T> 
class BitsetWrapper 
{ 
    using INDEX_TYPE = typename TypedefSelector<T>::IndexType; 
    ... 
}; 

, 당신은 컴파일시 오류가납니다.

+0

감사합니다. 단지'INDEX_TYPE'을 템플릿 매개 변수로 만들 수 있었기 때문에'BITSET'의 경우 3 (또는 일부 k의 경우 k) 유형에 제한이 없지만 인터페이스는 좀 더 성 가시고 , 추가 템플릿 매개 변수 때문에. 그래도 더 좋은 스타일은 무엇입니까? –

+0

@lotolmencre, 형식 공제 코드를 사용하는 것이 좋습니다. 오류가 발생하기 쉽습니다. –

관련 문제