2017-10-30 10 views
1

나는 C++ 98 (죄송합니다) 작성하지만, 형태의 데이터 구조에 저장되어 많은 개체가있는 C 라이브러리로 작업하고있어 : - 스타일의 반복BOOST_FOREACH를 포인터 유형으로 사용자 정의 할 수 있습니까?

struct c_container 
{ 
    size_t len; 
    int data[1]; 
}; 

struct c_container *make_container(size_t n) 
{ 
    if (n == 0) 
     return NULL; 
    struct c_container *rv = (struct c_container *)malloc(sizeof(rv->len) + n*sizeof(rv->data)); 
    rv->len = n; 
    return rv; 
} 

나는 C++을하고 싶습니다 BOOST_FOREACH을 사용하지만 이것이 작동하지 않습니다. (range_begin 및 range_end 함수를 수동으로 호출하는 "이전 스타일"이 작동합니다.)

inline int *range_begin(c_container *c) 
{ 
    return c ? &c->data[0] : NULL; 
} 
inline int *range_end(c_container *c) 
{ 
    return c ? &c->data[c->len] : NULL; 
} 
inline const int *range_begin(const c_container *c) 
{ 
    return c ? &c->data[0] : NULL; 
} 
inline const int *range_end(const c_container *c) 
{ 
    return c ? &c->data[c->len] : NULL; 
} 

namespace boost 
{ 
    template<> 
    struct range_mutable_iterator<c_container *> 
    { 
     typedef int *type; 
    }; 
    template<> 
    struct range_const_iterator<c_container *> 
    { 
     typedef const int *type; 
    }; 
} 

int main() 
{ 
    c_container *coll = make_container(3); 
    coll->data[0] = 1; 
    coll->data[1] = 42; 
    coll->data[2] = -1; 

    BOOST_FOREACH(int i, coll) 
    { 
     std::cout << i << std::endl; 
    } 
} 

내가 포인터를 사용하고있는 반면 모든 ,

그러나, 그 예는 클래스를 사용하여, 필요 http://www.boost.org/doc/libs/1_65_1/doc/html/foreach/extensibility.html에 따라 (내가 클래스와 함께 테스트 한)해야한다입니다 수업.

In file included from boost-foreach.cpp:6:0: 
/usr/include/boost/foreach.hpp: In function ‘bool boost::foreach_detail_::done(const boost::foreach_detail_::auto_any_base&, const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<T*, C>*) [with T = c_container, C = mpl_::bool_<false>, const boost::foreach_detail_::auto_any_base& = const boost::foreach_detail_::auto_any_base&]’: 
boost-foreach.cpp:65:5: instantiated from here 
/usr/include/boost/foreach.hpp:749:57: error: no match for ‘operator!’ in ‘!* boost::foreach_detail_::auto_any_cast [with T = c_container*, C = mpl_::bool_<false>, typename boost::mpl::if_<C, const T, T>::type = c_container*, const boost::foreach_detail_::auto_any_base& = const boost::foreach_detail_::auto_any_base&](((const boost::foreach_detail_::auto_any_base&)((const boost::foreach_detail_::auto_any_base*)cur)))’ 
/usr/include/boost/foreach.hpp:749:57: note: candidate is: operator!(bool) <built-in> 

몇 가지 추가 부스트를 전문으로하는 특성 또는 뭔가 거기에 내 조사를 바탕으로, 그것은 단지 const char *const wchar_t *위한 것입니다 코드 경로를 사용하는 것으로 나타 납니까?

답변

1

포인터의 범위 기능을 정의하는 것이 어려울 것으로 보이는 유형입니다. 하지만 c_container에 직접 정의 할 수 있습니다. 코드는 다음과 같습니다 다음 BOOST_FOREACH 루프가 포인터 타입을 통해 하지 반복 처리를하지

#include <cstdlib> 
#include <iostream> 
#include <boost/foreach.hpp> 

struct c_container 
{ 
    size_t len; 
    int data[1]; 
}; 

struct c_container *make_container(size_t n) 
{ 
    if (n == 0) 
     return NULL; 
    struct c_container *rv = (struct c_container *)malloc(sizeof(rv->len) + n * sizeof(rv->data)); 
    rv->len = n; 
    return rv; 
} 

inline int *range_begin(c_container &c) 
{ 
    return c.len > 0 ? &c.data[0] : NULL; 
} 
inline int *range_end(c_container &c) 
{ 
    return c.len > 0 ? &c.data[c.len] : NULL; 
} 
inline const int *range_begin(const c_container &c) 
{ 
    return c.len > 0 ? &c.data[0] : NULL; 
} 
inline const int *range_end(const c_container &c) 
{ 
    return c.len > 0 ? &c.data[c.len] : NULL; 
} 

namespace boost 
{ 
    template<> 
    struct range_mutable_iterator<c_container> 
    { 
     typedef int *type; 
    }; 
    template<> 
    struct range_const_iterator<c_container> 
    { 
     typedef const int *type; 
    }; 
} 

#define MY_FOREACH(x, y) BOOST_FOREACH(x, *y) 

int main() 
{ 
    c_container *coll = make_container(3); 
    coll->data[0] = 1; 
    coll->data[1] = 42; 
    coll->data[2] = -1; 

    //BOOST_FOREACH(int i, *coll) 
    MY_FOREACH(int i, coll) 
    { 
     std::cout << i << std::endl; 
    } 
} 

하는 것으로. 이 문제를 해결하려면 위에 나온 코드와 같이 자신의 FOREACH을 정의 할 수 있습니다.

+0

빈 컨테이너를 나타내는 NULL의 경우 실패합니다 ...하지만 어쨌든 클래스에 래핑 할 수있는 사용자 지정 매크로가 있다고 가정합니다. – o11c