这是我写的一些代码的简化版本:
#include <iostream>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/fusion/include/filter_if.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/pair.hpp>
#include <boost/fusion/include/io.hpp>
namespace ids{
struct a0{};
struct a1{};
struct a2{};
struct a3{};
};
typedef boost::fusion::map< boost::fusion::pair<ids::a0,int>
, boost::fusion::pair<ids::a1,double>
, boost::fusion::pair<ids::a2,char>
, boost::fusion::pair<ids::a3,long> > map_type;
typedef boost::mpl::vector<ids::a0,ids::a3> vec_ids_type;
template <typename T>
struct get_first
{
typedef typename T::first_type type;
};
typedef boost::fusion::result_of::filter_if<
map_type
, boost::mpl::contains<
vec_ids_type
, get_first<
boost::mpl::placeholders::_1
>
>
>::type view_type;
struct SetToZero
{
template <typename Field>
void operator()(Field & field) const
{
field.second = 0;
}
};
int main() {
map_type m( boost::fusion::make_pair<ids::a0>(1)
, boost::fusion::make_pair<ids::a1>(2.0)
, boost::fusion::make_pair<ids::a2>('a')
, boost::fusion::make_pair<ids::a3>(4)
);
std::cout << m << std::endl;
view_type v(m);
std::cout << v << std::endl;
boost::fusion::for_each(v,SetToZero());
std::cout << m << std::endl;
}
我想使用view_type
将map_type
实例中的某些元素设置为零。如果map_type
中的一个元素的键位于vec_ids_type
中,那么与该元素对应的数据必须设置为零,这可以通过调用仿函数SetToZero
来完成。要使所有这一切正常,T
在实例化fusion::pair
时应为get_first<T>
。
此代码使用boost 1.40和g ++ 4.4.3进行编译和运行。但是我试图使用更新版本的boost和g ++重新编译我的代码,并且我得到了编译错误。虽然我认为它与boost而不是编译器有关,但我还会提到g ++版本。首先我尝试使用boost 1.48.0.2和g ++ 4.6.3,然后尝试使用boost 1.49.0.1和g ++ 4.7.2。两次尝试都失败了,给出了非常相似的(如果不是相同的)编译错误。错误消息是:
tests.cpp: In instantiation of ‘struct get_first<ids::a0>’:
/usr/include/boost/mpl/aux_/has_type.hpp:20:1: required from ‘struct boost::mpl::aux::has_type<get_first<ids::a0>, mpl_::bool_<true> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/quote.hpp:32:36: required from ‘struct boost::mpl::quote1<get_first, mpl_::void_>::apply<ids::a0>’
/usr/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:36:8: required from ‘struct boost::mpl::apply_wrap1<boost::mpl::quote1<get_first, mpl_::void_>, ids::a0>’
/usr/include/boost/mpl/aux_/preprocessed/gcc/bind.hpp:144:21: [ skipping 16 instantiation contexts ]
/usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:101:135: required from ‘struct boost::mpl::aux::iter_fold_if_impl<boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0>, mpl_::na, boost::mpl::always<mpl_::bool_<false> > >’
/usr/include/boost/mpl/iter_fold_if.hpp:81:12: required from ‘struct boost::mpl::iter_fold_if<boost::mpl::vector<ids::a0, ids::a3>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, mpl_::na, mpl_::na>::result_’
/usr/include/boost/mpl/iter_fold_if.hpp:104:11: required from ‘struct boost::mpl::iter_fold_if<boost::mpl::vector<ids::a0, ids::a3>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, mpl_::na, mpl_::na>’
/usr/include/boost/mpl/find_if.hpp:39:17: required from ‘struct boost::mpl::find_if<boost::mpl::vector<ids::a0, ids::a3>, boost::mpl::same_as<get_first<mpl_::arg<1> > > >’
/usr/include/boost/mpl/find.hpp:28:8: required from ‘struct boost::mpl::find<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/aux_/contains_impl.hpp:33:54: required from ‘struct boost::mpl::contains_impl<boost::mpl::aux::vector_tag>::apply<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/contains.hpp:30:8: required from ‘struct boost::mpl::contains<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
tests.cpp:70:16: required from here
tests.cpp:37:34: error: no type named ‘first_type’ in ‘struct ids::a0’
In file included from /usr/include/boost/mpl/assert.hpp:17:0,
from /usr/include/boost/mpl/aux_/na_assert.hpp:23,
from /usr/include/boost/mpl/arg.hpp:25,
from /usr/include/boost/mpl/placeholders.hpp:24,
from /usr/include/boost/mpl/apply.hpp:24,
from /usr/include/boost/mpl/aux_/iter_apply.hpp:17,
from /usr/include/boost/mpl/aux_/find_if_pred.hpp:14,
from /usr/include/boost/mpl/find_if.hpp:17,
from /usr/include/boost/mpl/find.hpp:17,
from /usr/include/boost/mpl/aux_/contains_impl.hpp:20,
from /usr/include/boost/mpl/contains.hpp:20,
from tests.cpp:12:
/usr/include/boost/mpl/not.hpp: In instantiation of ‘struct boost::mpl::not_<boost::mpl::aux::iter_apply1<boost::mpl::same_as<get_first<mpl_::arg<1> > >, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> > >’:
/usr/include/boost/mpl/aux_/nested_type_wknd.hpp:26:31: required from ‘struct boost::mpl::aux::nested_type_wknd<boost::mpl::apply1<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> > >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/and.hpp:23:8: required from ‘struct boost::mpl::aux::and_impl<true, boost::mpl::apply1<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/and.hpp:48:8: required from ‘struct boost::mpl::and_<boost::mpl::not_<boost::is_same<boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> > >, boost::mpl::apply1<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >’
/usr/include/boost/mpl/iter_fold_if.hpp:40:58: required from ‘struct boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >::apply<void, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:46:8: required from ‘struct boost::mpl::apply_wrap2<boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0>, void, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/apply.hpp:67:8: [ skipping 4 instantiation contexts ]
/usr/include/boost/mpl/iter_fold_if.hpp:104:11: required from ‘struct boost::mpl::iter_fold_if<boost::mpl::vector<ids::a0, ids::a3>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, mpl_::na, mpl_::na>’
/usr/include/boost/mpl/find_if.hpp:39:17: required from ‘struct boost::mpl::find_if<boost::mpl::vector<ids::a0, ids::a3>, boost::mpl::same_as<get_first<mpl_::arg<1> > > >’
/usr/include/boost/mpl/find.hpp:28:8: required from ‘struct boost::mpl::find<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/aux_/contains_impl.hpp:33:54: required from ‘struct boost::mpl::contains_impl<boost::mpl::aux::vector_tag>::apply<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/contains.hpp:30:8: required from ‘struct boost::mpl::contains<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
tests.cpp:70:16: required from here
/usr/include/boost/mpl/not.hpp:39:8: error: ‘value’ is not a member of ‘boost::mpl::aux::nested_type_wknd<boost::mpl::aux::iter_apply1<boost::mpl::same_as<get_first<mpl_::arg<1> > >, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> > >’
In file included from /usr/include/boost/mpl/aux_/include_preprocessed.hpp:37:0,
from /usr/include/boost/mpl/and.hpp:42,
from /usr/include/boost/mpl/logical.hpp:18,
from /usr/include/boost/mpl/iter_fold_if.hpp:19,
from /usr/include/boost/mpl/find_if.hpp:19,
from /usr/include/boost/mpl/find.hpp:17,
from /usr/include/boost/mpl/aux_/contains_impl.hpp:20,
from /usr/include/boost/mpl/contains.hpp:20,
from tests.cpp:12:
/usr/include/boost/mpl/aux_/preprocessed/gcc/and.hpp: In instantiation of ‘struct boost::mpl::aux::and_impl<true, boost::mpl::apply1<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >’:
/usr/include/boost/mpl/aux_/preprocessed/gcc/and.hpp:48:8: required from ‘struct boost::mpl::and_<boost::mpl::not_<boost::is_same<boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> > >, boost::mpl::apply1<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >’
/usr/include/boost/mpl/iter_fold_if.hpp:40:58: required from ‘struct boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >::apply<void, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:46:8: required from ‘struct boost::mpl::apply_wrap2<boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0>, void, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/apply.hpp:67:8: required from ‘struct boost::mpl::apply2<boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0>, void, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:62:63: required from ‘struct boost::mpl::aux::iter_fold_if_forward_step<boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:101:135: [ skipping 2 instantiation contexts ]
/usr/include/boost/mpl/iter_fold_if.hpp:104:11: required from ‘struct boost::mpl::iter_fold_if<boost::mpl::vector<ids::a0, ids::a3>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, mpl_::na, mpl_::na>’
/usr/include/boost/mpl/find_if.hpp:39:17: required from ‘struct boost::mpl::find_if<boost::mpl::vector<ids::a0, ids::a3>, boost::mpl::same_as<get_first<mpl_::arg<1> > > >’
/usr/include/boost/mpl/find.hpp:28:8: required from ‘struct boost::mpl::find<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/aux_/contains_impl.hpp:33:54: required from ‘struct boost::mpl::contains_impl<boost::mpl::aux::vector_tag>::apply<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/contains.hpp:30:8: required from ‘struct boost::mpl::contains<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
tests.cpp:70:16: required from here
/usr/include/boost/mpl/aux_/preprocessed/gcc/and.hpp:23:8: error: ‘value’ is not a member of ‘boost::mpl::aux::nested_type_wknd<boost::mpl::apply1<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> > >’
In file included from /usr/include/boost/mpl/aux_/include_preprocessed.hpp:37:0,
from /usr/include/boost/mpl/aux_/iter_fold_if_impl.hpp:32,
from /usr/include/boost/mpl/iter_fold_if.hpp:25,
from /usr/include/boost/mpl/find_if.hpp:19,
from /usr/include/boost/mpl/find.hpp:17,
from /usr/include/boost/mpl/aux_/contains_impl.hpp:20,
from /usr/include/boost/mpl/contains.hpp:20,
from tests.cpp:12:
/usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp: In instantiation of ‘struct boost::mpl::aux::iter_fold_if_forward_step<boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0> >’:
/usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:101:135: required from ‘struct boost::mpl::aux::iter_fold_if_impl<boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0>, mpl_::na, boost::mpl::always<mpl_::bool_<false> > >’
/usr/include/boost/mpl/iter_fold_if.hpp:81:12: required from ‘struct boost::mpl::iter_fold_if<boost::mpl::vector<ids::a0, ids::a3>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, mpl_::na, mpl_::na>::result_’
/usr/include/boost/mpl/iter_fold_if.hpp:104:11: required from ‘struct boost::mpl::iter_fold_if<boost::mpl::vector<ids::a0, ids::a3>, void, mpl_::arg<1>, boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, mpl_::na, mpl_::na>’
/usr/include/boost/mpl/find_if.hpp:39:17: required from ‘struct boost::mpl::find_if<boost::mpl::vector<ids::a0, ids::a3>, boost::mpl::same_as<get_first<mpl_::arg<1> > > >’
/usr/include/boost/mpl/find.hpp:28:8: required from ‘struct boost::mpl::find<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/aux_/contains_impl.hpp:33:54: required from ‘struct boost::mpl::contains_impl<boost::mpl::aux::vector_tag>::apply<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
/usr/include/boost/mpl/contains.hpp:30:8: required from ‘struct boost::mpl::contains<boost::mpl::vector<ids::a0, ids::a3>, get_first<mpl_::arg<1> > >’
tests.cpp:70:16: required from here
/usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:62:63: error: no type named ‘type’ in ‘struct boost::mpl::apply2<boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0>, void, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >’
/usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:65:78: error: no type named ‘type’ in ‘struct boost::mpl::apply2<boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::mpl::same_as<get_first<mpl_::arg<1> > > >, 0>, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 2l> >, 0>, void, boost::mpl::v_iter<boost::mpl::vector<ids::a0, ids::a3>, 0l> >’
tests.cpp: In instantiation of ‘struct get_first<mpl_::arg<1> >’:
tests.cpp:70:16: required from here
tests.cpp:37:34: error: no type named ‘first_type’ in ‘struct mpl_::arg<1>’
从错误消息的第一行开始,tests.cpp: In instantiation of ‘struct get_first<ids::a0>’
对我来说完全出乎意料。这不应该发生,因为get_first
只应使用map_type
的元素进行实例化,即fusion::pair
。我真的不明白为什么会这样。
正如我所说,它与boost 1.40完美配合,它对我来说很有意义,因为它现在写了,所以我真的看不出错误在哪里。我唯一的猜测是,在导致这种情况的较新版本的fusion或mpl中可能会发生一些变化。实际上我检查了Boost.Fusion和Boost的更改日志,并且修改/添加了与融合视图相关的内容。也许是个bug?或者,我错过了什么?为什么它不适用于我尝试的较新版本的增强版?
提前感谢!
答案 0 :(得分:2)
使用:
typedef boost::fusion::result_of::filter_if<
map_type
,
boost::mpl::lambda<
boost::mpl::contains<
vec_ids_type
,
get_first<
boost::mpl::_1
>
>
>::type
>::type view_type;
似乎可以让它工作,你可以看到here。目前,LiveWorkspace使用boost 1.53.0。