【问题标题】:Boost Intrusive unordered_set broken in 1.48 with GCC in C++11 mode在 C++11 模式下使用 GCC 在 1.48 中破坏了 Boost Intrusive unordered_set
【发布时间】: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 &amp;&amp;,但如果定义了BOOST_NO_RVALUE_REFERENCES,则它变为const TYPE &amp;。如果我确实这样定义它,代码就会编译!

有什么想法吗?是 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


【解决方案1】:

这看起来与http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53234 中描述的问题相同

即Boost 1.48 假定 GCC 4.6 的旧行为,但 GCC 4.7 进行了更改以实现有关隐式定义的复制/移动构造函数的正确 C++11 语义。

【讨论】:

    猜你喜欢
    • 2012-09-30
    • 2020-06-21
    • 2015-01-06
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多