2012-03-06 2 views
0

가변 템플릿을 사용하여 Boost MPL과 같은 vector_c를 작성하는 방법을 궁금합니다. 나는 이미 코드를 다음 코드 작성 :가변 템플릿이있는 MPL 유사 벡터 : 삽입

template <std::size_t element, std::size_t ... E> 
struct vector 
{ 
    typedef vector<E ...> next; 

    static constexpr std::size_t size() 
    { 
     return sizeof... (E); 
    } 

    static constexpr std::size_t value() 
    { 
     return element; 
    } 
}; 

template <std::size_t element> 
struct vector<element> 
{ 
    // no need to define 'next' here 

    static constexpr std::size_t size() 
    { 
     return 1; 
    } 

    static constexpr std::size_t value() 
    { 
     return element; 
    } 
}; 

당신은 vector가 적어도 하나 개의 요소가 있어야합니다 것을 알 수 있습니다,하지만 그건 정말 나를 위해 제한되지 않습니다. 상기 정의로, 주어진 인덱스 요소를 액세스하기 위해 "함수"를 쓸 매우 쉽다 : 예를 들어

template <std::size_t index, typename T> 
struct get 
{ 
    typedef typename get<index - 1, typename T::next>::type type; 
}; 

template <typename T> 
struct get<0, T> 
{ 
    typedef T type; 
}; 

get<1, vector<1, 2, 3>>2 올바른 결과를 반환한다. 이제 내 질문 : 어떻게 삽입 기능을 구현하나요? MPL을 사용하지 않는 이유는 insert<>을 시도했을 때 vector_c을 반환하지 않았기 때문입니다. 특히, 삽입과 같이 적용한다 :

insert<vector<1, 3, 4>, 1, 2>::type 
// ^   ^^ 
//  type   at element 

해야 수율 vector<1, 2, 3, 4>. 가능한가?

답변

2

,

insert list 0 element = element : list 
insert list at element = (head list) : insert (tail list) (at-1) element 

C++ 템플릿이 번역 :

// insert list at element = 
template <typename List, size_t at, size_t element> 
struct Insert 
{ 
    typedef typename 
     // insert (tail list) (at-1) element 
     Insert<typename List::next, at-1, element>::type:: 
     // (head list) : … 
     template push_front<List::value()>::type 
    type; 
}; 

// insert list 0 element = 
template <typename List, size_t element> 
struct Insert<List, 0, element> 
{ 
    // element : list 
    typedef typename List::template push_front<element>::type type; 
}; 

참고 두 vector 년대의 원시 push_front를 정의해야

template <std::size_t element, std::size_t ... E> 
struct vector<element, E...> 
{ 
    template <size_t x> 
    struct push_front 
    { 
     typedef vector<x, element, E...> type; 
    }; 
}; 
+0

멋진 솔루션 - MPL을 다양한 방식으로 재 작성/대체 할 수있는 방법에 대한 통찰력을 얻을 수 있습니다. – mark

+0

그 동안 나는'push_front' 함수를 써야한다는 결론에 도달했습니다. 그러나 벡터 자체 안에 있어야한다는 것을 깨닫지 못했습니다! vector 클래스 밖에서 push_front를 작성하는 것은 불가능하다고 생각합니다. 맞습니까? – cschwan

+1

@cschwan : 물론 * can * (예 : http://ideone.com/3F4UQ). 나는 그 일을하는 것을 괴롭히지 않는다. – kennytm

1

삽입 후 MPL이 vector_c를 반환하도록하려면 vector_c as_vector를 사용하여 MPL을 벡터화해야합니다.

반 기능적 언어를 여기에서 다루고 있습니다. 삽입하고 싶다면 이전 버전과 색인/위치에서 새 vector_c를 다시 작성해야합니다. 재구성이 매우 지루한 것처럼 MPL은 벡터 (정적 시퀀스 개념을 따름)로 작동하는 유형을 반환하고 위치 N이 필요할 때 삽입 값을 확인하여보고있는 과부하를 <> 얻습니다. 무엇을 돌려 줄까요?

하스켈의 관점에서
+0

설명 주셔서 감사합니다 - 어디에서 'as_vector'를 찾을 수 있습니까? – cschwan

관련 문제