【发布时间】:2012-05-13 12:39:54
【问题描述】:
如果您安装 GCC 4.7 和 Boost 1.48 附带的 Fedora 17 并使用 C++11 模式,则 Boost Intrusive 的 unordered_set 会损坏。在带有 GCC 4.6.2 和 Boost 1.47 的 Fedora 16 上,它可以工作。这破坏了真实的代码,甚至破坏了official documentation中的示例:
#include <boost/intrusive/unordered_set.hpp>
using namespace boost::intrusive;
struct MyClass : public unordered_set_base_hook<>
{};
typedef unordered_set<MyClass>::bucket_type bucket_type;
typedef unordered_set<MyClass>::bucket_traits bucket_traits2;
int main()
{
bucket_type buckets[100];
unordered_set<MyClass> uset(bucket_traits2(buckets, 100)); // FAILS
}
错误信息:
/usr/include/boost/intrusive/hashtable.hpp:227:65: 错误:使用已删除的函数 'constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost: :intrusive::detail::bucket_traits_impl >::type>&)'
在 /usr/include/boost/intrusive/hashtable.hpp:30:0 包含的文件中, 来自 /usr/include/boost/intrusive/unordered_set.hpp:18, 来自 t.cpp:23:
/usr/include/boost/intrusive/detail/hashtable_node.hpp:80:8: 注意:'constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost::intrusive ::detail::bucket_traits_impl >::type>&)' 被隐式声明为已删除,因为 'boost::intrusive::detail::bucket_traits_impl >::type>' 声明了移动构造函数或移动赋值运算符
这里是它引用的代码,hashtable.hpp:227:
template<class BucketTraits>
bucket_plus_size(BOOST_FWD_REF(BucketTraits) b_traits)
: bucket_traits_(::boost::forward<BucketTraits>(b_traits))
{}
在 Boost 1.47 中,这是:
bucket_plus_size(const bucket_traits &b_traits)
: bucket_traits_(b_traits)
{}
我系统上的BOOST_FWD_REF(TYPE) 默认定义为TYPE &&,但如果定义了BOOST_NO_RVALUE_REFERENCES,则它变为const TYPE &。如果我确实这样定义它,代码就会编译!
有什么想法吗?是 GCC 的错、Boost、Fedora 的错还是我的错?
【问题讨论】:
-
一个好的开始是使用 Boost 1.49.0 进行测试,以防它是一个已经修复的侵入性(或配置)错误。
-
我使用 Boost 1.49 和 GCC 4.7.0(与 OP 中的相同)对其进行了测试,并且可以正常工作,但这是在 Mac OS 上而不是在 Fedora 上。
-
Boost 1.48 中 intrusive::unordered_set 的第二个问题是 BOOST_FOREACH 失败。我想知道 Fedora 包的维护者是否应该考虑在 Boost 的 config.hpp 中定义 BOOST_NO_RVALUE_REFERENCES,这样其他人就不必这样做了。
-
既然 Boost 1.49 已经可以使用,他们为什么还要这样做?
-
不过,这是一种“传染性”的方法:一旦你这样做了,你就会走上从源代码构建大量东西的道路,因为你可以从 yum 存储库获得的其他包将取决于在 Boost 上,因此从源代码制作 Boost 可能会迫使您也从源代码构建其他东西。这在某些系统上被认为是正常的,但在 Fedora 或 Ubuntu 上并不正常,即使第三方库行为不端,分销商也应该保持某种秩序。
标签: c++ gcc boost c++11 intrusive-containers