2010-01-28 4 views
2

이것은 TTL에서이다 : 그것은이 TypeList에 typeswitching을 위해 사용되는유형 목록에 대한 런타임 유형 스위치가 중첩 된 if 대신 스위치로 사용됩니까?

//////////////////////////////////////////////////////////// 
// run-time type switch 
template <typename L, int N = 0, bool Stop=(N==length<L>::value) > struct type_switch; 

template <typename L, int N, bool Stop> 
    struct type_switch 
    { 
    template< typename F > 
     void operator()(size_t i, F& f) 
     { 
     if(i == N) 
     { 
      f.operator()<typename impl::get<L,N>::type>(); 
     } 
     else 
     { 
      type_switch<L, N+1> next; 
      next(i, f); 
     } 
     } 
    }; 

. 질문은 - 그들은 일련의 중첩 된 if를 통해 이것을 수행합니다. 단일 SELECT 문 대신이 유형 스위치를 수행하는 방법이 있습니까?

감사합니다.

+0

실제 사용되는 구조는 무엇입니까? – Potatoswatter

+0

최근의 clang은 이런 종류의 것을 점프 테이블로 변환 할 수 있습니다 : https://godbolt.org/g/Nco0Al, GCC는 (동일한 옵션으로) https://godbolt.org/g/4VL9e7 할 수 없습니다. – user877329

답변

2

switch을 생성하려면 전 처리기가 필요합니다. 아웃 바운드 조회를 수행하지 않으려면 get<>이 필요합니다. 컴파일러 출력을 검사하여 사용하지 않는 케이스가 출력을 생성하지 않도록하십시오. 필요에 따라 조정;

체크 아웃 당신이 이런 종류의 좋은 얻기 위해 신경 경우 부스트 전 처리기 라이브러리 ...

template <typename L> 
    struct type_switch 
    { 
    template< typename F > 
     void operator()(size_t i, F& f) 
     { 
     switch (i) { 
     #define CASE_N(N) \ 
     case (N): return f.operator()<typename impl::get<L,N>::type>(); 
     CASE_N(0) 
     CASE_N(1) 
     CASE_N(2) 
     CASE_N(3) // ad nauseam. 
     } 
    }; 
+0

* ad nauseam *이라면 스위치가 잠재적으로 유효하지 않은 N과 함께 템플릿을 인스턴스화하려고 시도하고 모든 것이 컴파일되지 않는다는 것을 의미하지 않을까요? 재귀는 멈추는 위치를 알고,이 스위치는 분명히하지 않습니다. (기본적으로 전체 스위치 아이디어가 완전히 잘못된 것 같아서 템플릿 메타 프로그래밍을 할 수있는 방법이 아닙니다.) IMO, 컴파일 타임 스위치는 재귀를 통해 만든 if-chain 이외의 것입니다. – UncleBens

+0

@UncleBens : That 's 나는 "no-op out-of-bound lookups"을 의미했다. typelist 템플릿은'get <>'에서 재귀를 구현합니다. 그것은 범위를 벗어난 인덱스를 찾아서 아무것도 반환하지 않아야합니다. if-chain보다 이점은 컴파일러와 애플리케이션에 달려있다. 중복 질문에 대한 대답에 따르면, boost :: variant (훨씬 더 잘 알려진 예제)는 여기에 설명 된 기술을 사용합니다. – Potatoswatter

+0

답변을 한 후 거의 같은 질문을 두 번이나하는 것에 대해 사과하고 싶습니다. 문제 - 처음에는 대답을 이해하지 못했습니다. 그러나 이제는 그것을 이해할 수있게되었는데, 왜 다른 질문들이 중복되는지 알 수 있습니다. – anon

0

나는 그렇게 생각하지 않는다.

이러한 유형의 메타 프로그래밍은 일반적으로 재귀를 통해 수행됩니다. 컴파일 타임에 모든 일이 발생하기 때문에 런타임 재귀 나 조건 확인이 없으면 놀라지 않을 것입니다.

0

당신은 항상 대신 선형 검색 이진 검색을 사용할 수 있습니다. 더 복잡하고 버그가있을 가능성이 더 높습니다 (바이너리 검색은 놀라 울 정도로 엉망이되기 쉽습니다).

또한 수동으로 N type_switch::operator()을 확장 할 수 있습니다. N은 프로그램에서 사용할 수있는 유형 목록 길이의 합리적인 상한선입니다.