BOOST_FOREACH在模板内不起作用?

时间:2012-07-13 18:37:38

标签: c++ templates boost

我尝试在模板函数中使用BOOST_FOREACH,使用自定义但类型参数独立的迭代器。我得到4-5个错误,表明我的迭代器类没有很好地定义为迭代器。

在没有BOOST_FOREACH的情况下重写循环,或者“取消模板化”函数会使错误消失。

这是BOOST_FOREACH的已知限制吗?

EDIT。

对不起。一些代码:

template <class T>
T fun()
{
    T result(0.0);

    BOOST_FOREACH(const math::IntegerVector &v, math::IntegerVectorRange(math::IntegerVector(2 , 2 ,2)))
    {
        // Do stuff.
    }

    return result;
}

IntegerVector *类型定义良好,在模板外工作正常。他们也不依赖于T.

完整的错误是:

make[1]: Entering directory `/home/panayk/Workspace/petros-game'
Making all in src/c++
make[2]: Entering directory `/home/panayk/Workspace/petros-game/src/c++'
depbase=`echo fluid/Tracer.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
    /bin/bash ../../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I../..   -I/usr/include/python2.7 -I/usr/include -O2 -I/usr/include/python2.7 -MT fluid/Tracer.lo -MD -MP -MF $depbase.Tpo -c -o fluid/Tracer.lo fluid/Tracer.cc &&\
    mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I../.. -I/usr/include/python2.7 -I/usr/include -O2 -I/usr/include/python2.7 -MT fluid/Tracer.lo -MD -MP -MF fluid/.deps/Tracer.Tpo -c fluid/Tracer.cc  -fPIC -DPIC -o fluid/.libs/Tracer.o
In file included from /usr/include/boost/iterator/iterator_categories.hpp:15:0,
                 from /usr/include/boost/iterator/detail/facade_iterator_category.hpp:7,
                 from /usr/include/boost/iterator/iterator_facade.hpp:14,
                 from ./math/Vector.h:5,
                 from ./fluid/Tracer.h:4,
                 from fluid/Tracer.cc:1:
/usr/include/boost/mpl/eval_if.hpp: In instantiation of 'boost::mpl::eval_if<mpl_::bool_<false>, boost::range_const_iterator<math::IntegerVectorRange>, boost::range_mutable_iterator<math::IntegerVectorRange> >':
/usr/include/boost/foreach.hpp:364:13:   instantiated from 'boost::foreach_detail_::foreach_iterator<math::IntegerVectorRange, mpl_::bool_<false> >'
make[2]: Leaving directory `/home/panayk/Workspace/petros-game/src/c++'
./fluid/InterpolatorGrid.h:45:3:   instantiated from here
make[1]: Leaving directory `/home/panayk/Workspace/petros-game'
/usr/include/boost/mpl/eval_if.hpp:38:31: error: no type named 'type' in 'boost::mpl::eval_if<mpl_::bool_<false>, boost::range_const_iterator<math::IntegerVectorRange>, boost::range_mutable_iterator<math::IntegerVectorRange> >::f_ {aka struct boost::range_mutable_iterator<math::IntegerVectorRange>}'
In file included from fluid/Tracer.cc:3:0:
./fluid/InterpolatorGrid.h: In member function 'T fluid::InterpolatorGrid::interpolate(const std::vector<std::vector<std::vector<T> > >&, const RealVector&) const':
./fluid/InterpolatorGrid.h:45:3: error: no matching function for call to 'begin(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<math::IntegerVectorRange, mpl_::bool_<false> >*, boost::enable_if_c<true, boost::mpl::and_<boost::mpl::not_<boost::foreach::is_noncopyable<math::IntegerVectorRange> >, boost::foreach::is_lightweight_proxy<math::IntegerVectorRange>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> > >::type*&)'
./fluid/InterpolatorGrid.h:45:3: note: candidates are:
/usr/include/boost/foreach.hpp:657:1: note: template<class T, class C> boost::foreach_detail_::auto_any<typename boost::foreach_detail_::foreach_iterator<T, C>::type> boost::foreach_detail_::begin(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T, C>*, mpl_::true_*)
/usr/include/boost/foreach.hpp:665:1: note: template<class T, class C> boost::foreach_detail_::auto_any<typename boost::foreach_detail_::foreach_iterator<T, C>::type> boost::foreach_detail_::begin(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T, C>*, mpl_::false_*)
/usr/include/boost/foreach.hpp:676:1: note: template<class T> boost::foreach_detail_::auto_any<typename boost::foreach_detail_::foreach_iterator<T, mpl_::bool_<true> >::type> boost::foreach_detail_::begin(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T, mpl_::bool_<true> >*, bool*)
/usr/include/boost/foreach.hpp:686:1: note: template<class T, class C> boost::foreach_detail_::auto_any<T*> boost::foreach_detail_::begin(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T*, C>*, mpl_::true_*)
./fluid/InterpolatorGrid.h:45:3: error: no matching function for call to 'end(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<math::IntegerVectorRange, mpl_::bool_<false> >*, boost::enable_if_c<true, boost::mpl::and_<boost::mpl::not_<boost::foreach::is_noncopyable<math::IntegerVectorRange> >, boost::foreach::is_lightweight_proxy<math::IntegerVectorRange>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> > >::type*&)'
./fluid/InterpolatorGrid.h:45:3: note: candidates are:
/usr/include/boost/foreach.hpp:697:1: note: template<class T, class C> boost::foreach_detail_::auto_any<typename boost::foreach_detail_::foreach_iterator<T, C>::type> boost::foreach_detail_::end(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T, C>*, mpl_::true_*)
/usr/include/boost/foreach.hpp:705:1: note: template<class T, class C> boost::foreach_detail_::auto_any<typename boost::foreach_detail_::foreach_iterator<T, C>::type> boost::foreach_detail_::end(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T, C>*, mpl_::false_*)
/usr/include/boost/foreach.hpp:716:1: note: template<class T> boost::foreach_detail_::auto_any<typename boost::foreach_detail_::foreach_iterator<T, mpl_::bool_<true> >::type> boost::foreach_detail_::end(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T, mpl_::bool_<true> >*, bool*)
/usr/include/boost/foreach.hpp:726:1: note: template<class T, class C> boost::foreach_detail_::auto_any<int> boost::foreach_detail_::end(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T*, C>*, mpl_::true_*)
./fluid/InterpolatorGrid.h:45:3: error: no matching function for call to 'deref(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<math::IntegerVectorRange, mpl_::bool_<false> >*)'
./fluid/InterpolatorGrid.h:45:3: note: candidate is:
/usr/include/boost/foreach.hpp:765:1: note: template<class T, class C> typename boost::foreach_detail_::foreach_reference::type boost::foreach_detail_::deref(boost::foreach_detail_::auto_any_t, boost::foreach_detail_::type2type<T, C>*)
make[2]: *** [fluid/Tracer.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

等。这对我来说太难以解密,但IntegerVectorRange :: begin()就在那里并返回一个const_iterator。 IntegerVectorRange :: end()也是如此。

EDIT2(IntegerVectorRange stuff)

class IntegerVectorIterator
: public boost::iterator_facade
<
    IntegerVectorIterator,
    const IntegerVector,
    boost::forward_traversal_tag
>
{
private:
    IntegerVector current;
    const IntegerVector start, limit;

    void increment();
    bool equal(const IntegerVectorIterator& other) const;
    const IntegerVector &dereference() const;

public:
    IntegerVectorIterator(const IntegerVector &start,
                          const IntegerVector &limit);
    IntegerVectorIterator(const IntegerVector &current,
                          const IntegerVector &start,
                          const IntegerVector &limit);

    friend class boost::iterator_core_access;
};

class IntegerVectorRange
{
private:
    const IntegerVector start, limit;
    const IntegerVectorIterator end_it;
public:
    IntegerVectorRange(IntegerVector limit);
    IntegerVectorRange(IntegerVector start, IntegerVector limit);

    typedef IntegerVectorIterator const_iterator;

    const_iterator begin() const;
    const const_iterator &end() const;
};

1 个答案:

答案 0 :(得分:1)

对失踪的课程进行打击,GCC不喜欢它:http://ideone.com/3O3OB。 Clang ++编译得很好。所以,我猜你有一个编译器错误,或者可能是#ifdefs中所有boost/foreach.hpp中的错误

特别说明这是实例化回溯的一部分:

eval_if<bool_<false>, range_const_iterator<...>, range_mutable_iterator<...> >

建议无论BOOST_FOREACH使用什么机制来确定你是否可变迭代或const迭代,这次都会得到错误答案。