2013-05-03 5 views
7

TR1 랜드에 고정되어 있으므로 테스트 프로그램에서 특정 유형의 객체에 대해 특정 작업을 수행해야합니다. 다음과 같은 두 개의 튜플 유형 정의가 있습니다.TR1 튜플을 반복하는 방법

typedef std::tr1::tuple< bool 
         , signed char 
         , signed short 
         , signed int 
         , signed long long 
         , unsigned char 
         , unsigned short 
         , unsigned int 
         , unsigned long long > integral_types; 

각 튜플 유형에서 개체가 만들어집니다. 다음과 비슷한 함수 템플릿이 있습니다.

template<typename T> 
void invoke_operation_1(T& obj); 

튜플 개체의 모든 개체에 대해 호출해야합니다.

C++ 03에서는 어떻게합니까?

+1

이 (http://mattgemmell.com/2008/12/08/what-have-you-tried/가) –

+0

이없는'tuple_size' 그리고 tr1에서'get'합니까? – jrok

+0

[Boost.Fusion 접근 방식] (http://stackoverflow.com/a/1201902/560648)은 C++ 03과 호환되어야합니다. [수동 접근] (http://stackoverflow.com/a/1198432/560648)이 여기에 있습니다. –

답변

3

튜플의 모든 개체에 대해 동일한 템플릿 기능을 호출해야하는 경우 boost::fusion을 사용할 수 있습니다. 예 : [지금까지 시도 무엇?]

template<typename T> 
void invoke_operation_1(T& obj) 
{ 
    std::cout << obj << std::endl; 
} 

struct executor 
{ 
    template<typename T> 
    void operator()(T& t) const 
    { 
     invoke_operation_1(t); 
    } 
}; 

typedef boost::tuple< bool 
         , signed char 
         , signed short 
         , signed int 
         , signed long long 
         , unsigned char 
         , unsigned short 
         , unsigned int 
         , unsigned long long > integral_types; 
int main() 
{ 
    integral_types t(true, 0, 1, 2, 3, 4, 5, 6, 7); 
    boost::fusion::for_each(t, executor()); 
    return 0; 
} 
+0

나는 그것을하기 위해 boost :: fusion을 가져 오는 것을 주저했지만, 이것은 매우 편리해 보인다. 그래서 나는 어쨌든 시도해보십시오. '집행자'는 어떤 조건을 충족해야합니까? 대신'std :: tr1 :: bind()'표현식이 작동할까요? 인수 자리 표시자를 사용합니까? – sbi

+0

@sbi 문서에 '정규 호출 가능 객체'가있어 바인드 표현식을 확인해야합니다. – mkaes

+0

@sbi'invoke_operation_1'은 템플릿이 아니고 함수가 아니기 때문에'boost :: bind'가 작동하지 않을지 의심 스럽습니다. 적어도 필자는 여기에 필요한 템플릿 템플릿 인수를 사용하는 오버로드를 찾을 수 없었습니다. –

8

바로이 문제를 해결하기 위해 C++ 14의 Bristol에서 완성 된 기능이 있습니다. 처리하기가 너무 어렵지 않습니다.

단순한 경우 재귀 템플릿을 사용할 수 있습니다. 부분 기능 전문화 등이 없어도 혼란 스러울 지경입니다.

template<typename Tup, std::size_t N> struct visit_detail { 
    template<typename F> static void call(Tup& t, F f) { 
     f(std::tr1::get<N>(t)); 
     return visit_detail<Tup, N+1>::call(t, f); 
    } 
}; 
template<typename Tup> struct visit_detail<Tup, std::tr1::tuple_size<Tup>::value> { 
    template<typename F> static void call(Tup& t, F f) {} 
} 

template<typename Tup, typename F> void visit(Tup& t, F f) { 
    return visit_detail<Tup, 0>::call(t, f); 
} 

여기서 f는 하드 코딩되거나 매개 변수 함수 개체 또는 원하는 것일 수 있습니다.

+0

아, 실제로 '튜플 크기'가 있습니다. 고마워, 내가 거기에서 그것을 해결할 수 있다고 생각해! – sbi

+0

@DeadMG : Yikes! 참고로 C++ 14 기능의 이름을 기억할 수 있습니까? –

+0

[N3493] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3493.html) 약간 수정 된 – Puppy

0
template<typename tup, typename N> 
struct visit_detailImpl { 
    template<typename f> 
    static void call(tup& t, f f) { 
     f(std::tr1::get<N::value>(t)); 
     return visit_detailImpl<tup, std::integral_constant<std::size_t, N::value + 1> >::call(t, f); 
    } 
}; 
template<typename tup> // end recursion struct 
struct visit_detailImpl<tup, std::integral_constant<std::size_t, std::tr1::tuple_size<tup>::value> > { 
    template<typename f> 
    static void call(tup& t, f f) {} 
}; 
template<typename tup, typename Fn> 
void for_each_tup(tup& t, Fn f) { 
    return visit_detailImpl<tup, std::integral_constant<std::size_t, 0> >::call(t, f); 
} 
+0

"TR1 땅에 갇혀있는 ..." – sbi