我正在编写C ++ 98(对不起),但是使用C库,它有许多对象存储在表单的数据结构中:
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;
}
我想使用BOOST_FOREACH
进行C ++样式的迭代,但这不起作用。 ("旧样式"手动调用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(我已经用类测试过它),这就是应该的全部内容
但是,该示例使用类,而我使用指向类的指针。根据我的调查,它似乎使用的代码路径仅适用于const char *
和const wchar_t *
:
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>
是否有一些额外的提升特性专门化或什么?
答案 0 :(得分:1)
似乎很难为指针类型定义范围函数。但您可以直接为c_container
定义它们。代码如下所示:
#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;
}
}
请注意,BOOST_FOREACH
循环不迭代指针类型。作为解决方法,您可以定义自己的FOREACH
,如上面的代码所示。