gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 01:53:40 24 4
gpt4 key购买 nike

考虑以下代码,使用 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;
}

鉴于 boost 版本 1.48,代码无法使用 clang 3.2 (SVN) 和 gcc 4.6.3,但适用于 gcc 4.5.3。使用非 const 限定参数 xsiterate 代码可以工作。启用 C++11 后,所有编译器都接受代码。当使用 boost-1.46 时,两个 gcc 版本都接受代码,但 clang 仍然不接受。

手头的代码是对 BOOST_FOREACH 宏的误用,还是 boosts 方面的错误?有没有比使用常规 for 循环迭代更好的解决方法?

编辑:我将 GCC 的错误消息粘贴到 pastebin(两者都非常冗长)和 clang .

最佳答案

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

简短版:出于某种原因BOOST_FOREACH试图复制不可能的数据。

Extensibility 上有注释页:

Making BOOST_FOREACH Work with Non-Copyable Sequence Types

For sequence types that are non-copyable, we will need to tell BOOST_FOREACH to not try to make copies. If our type inherits from boost::noncopyable, no further action is required. If not, we must specialize the boost::foreach::is_noncopyable<> template [...] Another way to achieve the same effect is to override the global boost_foreach_is_noncopyable() function. Doing it this way has the advantage of being portable to older compilers.

从诊断来看,不清楚类型是否配置正确,因此您可能想试一试。


修剪诊断和分析。

/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())
^

我试图尽可能地隔离错误(删除回溯等)显然问题源于 boost::intrusive::list ,更准确地说,无法构建新的 boost::intrusive::list<>来自boost::intrusive::list<> const .

最有前途的构造函数由宏定义:

BOOST_MOVABLE_BUT_NOT_COPYABLE(list)

扩展为

list(list&);

这是 boost 在 C++03 中模拟不可复制类型的移动语义的方式。但是它不能从 const 移动。自 const 以来的项目限定符将丢失。

这看起来是 BOOST_FOREACH 使用的诡计的一部分 |为了避免对容器参数进行多次评估(如果它是函数调用),尽管我有点惊讶它试图在此处复制参数。

关于c++ - 将 BOOST_FOREACH 与常量侵入列表一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10836399/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com