C++ 将BOOST_FOREACH与常量侵入列表一起使用

C++ 将BOOST_FOREACH与常量侵入列表一起使用,c++,boost,boost-foreach,intrusive-containers,C++,Boost,Boost Foreach,Intrusive Containers,考虑使用BOOST_FOREACH宏在入侵列表上迭代的以下代码: #include <boost/foreach.hpp> #include <boost/intrusive/list.hpp> typedef boost::intrusive::list< boost::intrusive::list_base_hook<> > MyList; void iterate (const MyList& xs) { BOO

考虑使用BOOST_FOREACH宏在入侵列表上迭代的以下代码:

#include <boost/foreach.hpp>
#include <boost/intrusive/list.hpp>

typedef boost::intrusive::list<
    boost::intrusive::list_base_hook<> > MyList;

void iterate (const MyList& xs) {
    BOOST_FOREACH (MyList::const_reference node, xs);
}

int main () {
    MyList xs;
    iterate (xs);
    return 0;
}
#包括
#包括
typedef boost::侵入::列表<
boost::intrusive::list\u base\u hook>MyList;
无效迭代(常量MyList&xs){
BOOST_FOREACH(MyList::const_引用节点,xs);
}
int main(){
MyList xs;
迭代(xs);
返回0;
}
给定boost版本1.48,代码在Clang3.2(SVN)和GCC4.6.3中失败,但在GCC4.5.3中工作。使用非常量限定参数
xs
iterate
时,代码工作。启用C++11后,所有编译器都接受该代码。使用boost-1.46时,两个gcc版本都接受该代码,但clang仍然不接受

手头的代码是误用了
BOOST\u FOREACH
宏,还是boosts端的错误?有没有比使用常规for循环的迭代更好的解决方法

编辑:
我已将错误消息粘贴到和的pastebin(两者都非常详细)。

由于您使用的是gcc>4.6和clang 3.2,您可以使用C++11的基于范围的looops:

#include <boost/foreach.hpp>
#include <boost/intrusive/list.hpp>

typedef boost::intrusive::list<
    boost::intrusive::list_base_hook<> > MyList;

void iterate (const MyList& xs) {
    for(const auto &node : xs) {
        // do something with node
    }
}

int main () {
    MyList xs;
    iterate (xs);
    return 0;
}

以下是我可以从日志中收集到的信息,以及我对失败原因的推断

短版本:出于某种原因,BOOST\u FOREACH试图复制不可能的数据

页面上有一个注释:

使用不可复制的序列类型制作
BOOST\u FOREACH

对于不可复制的序列类型,我们需要告诉
BOOST\u FOREACH
不要尝试复制。如果我们的类型继承自
boost::noncopyable
,则无需进一步操作。如果没有,我们必须专门化
boost::foreach::is_noncopyable
模板[…]实现相同效果的另一种方法是重写全局
boost\u foreach\u is_noncopyable()
函数。这样做的好处是可以移植到较旧的编译器

从诊断结果来看,不清楚该类型是否正确配置,因此您可能希望尝试一下


删减诊断和分析

/usr/include/boost/foreach.hpp:571:37: error: no matching constructor for initialization of 'boost::intrusive::list< >'
        ::new(this->data.address()) T(t);
                                    ^ ~
/usr/include/boost/foreach.hpp:648:51: note: in instantiation of member function 'boost::foreach_detail_::simple_variant<boost::intrusive::list< > >::simple_variant' requested here
    return auto_any<simple_variant<T> >(*rvalue ? simple_variant<T>(t) : simple_variant<T>(&t));
                                                  ^

/usr/include/boost/intrusive/list.hpp:1490:35: note: candidate constructor not viable: 1st argument ('const boost::intrusive::list< >') would lose const qualifier
   BOOST_MOVABLE_BUT_NOT_COPYABLE(list)
                                  ^
/usr/include/boost/move/move.hpp:371:7: note: expanded from macro 'BOOST_MOVABLE_BUT_NOT_COPYABLE'
      TYPE(TYPE &);\

/usr/include/boost/intrusive/list.hpp:1497:4: note: candidate constructor not viable: no known conversion from 'const boost::intrusive::list< >' to 'const value_traits' (aka 'const boost::intrusive::detail::base_hook_traits<boost::intrusive::list_base_hook< >, boost::intrusive::list_node_traits<void *>, 1, boost::intrusive::default_tag, 1>') for 1st argument; 
   list(const value_traits &v_traits = value_traits())
   ^
/usr/include/boost/intrusive/list.hpp:1506:4: note: candidate constructor not viable: no known conversion from 'const boost::intrusive::list< >' to '::boost::rv<list< >> &' for 1st argument; 
   list(BOOST_RV_REF(list) x)
   ^
/usr/include/boost/intrusive/list.hpp:1502:4: note: candidate constructor template not viable: requires at least 2 arguments, but 1 was provided
   list(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
   ^
扩展到

list(list&);
这是boost在C++03中模拟不可复制类型的移动语义的方式。但是,它不能从
const
项移动,因为
const
限定符将丢失


这似乎是
BOOST\u FOREACH
所使用的伎俩的一部分,以避免对容器参数进行多次求值(如果它是函数调用),尽管我有点惊讶它试图在这里复制参数。

或者接受BOOST不支持clang?不可接受。gcc-4.6.3仍然会失败,我最终会编写常规的for-loops。如果我们真的能看到两个编译器的错误消息,那就太酷了。使用了pastebin,因为错误非常详细。非常好的建议,但不幸的是C++03兼容性需要维护。谢谢!正是我想要的。
BOOST_MOVABLE_BUT_NOT_COPYABLE(list)
list(list&);