提升侵入unordered_set在 1.48 中被打破,GCC 处于 C++11 模式

Boost Intrusive unordered_set broken in 1.48 with GCC in C++11 mode

本文关键字:GCC 模式 C++11 处于 unordered set      更新时间:2023-10-16

如果你对GCC 4.7和Boost 1.48附带的Fedora 17进行普通安装,并使用C++11模式,Boost Intrusive的unordered_set就会被破坏。 在 GCC 4.6.2 和 Boost 1.47 附带的 Fedora 16 上,它可以工作。 这破坏了真实的代码,甚至破坏了官方文档中的示例:

#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::d etail::bucket_traits_impl>::type>::bucket_traits_impl(const boost::intrusive::d etail::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::d etail::bucket_traits_impl>::type>::bucket_traits_impl(const boost::intrusive::d etail::bucket_traits_impl>::type>&("被隐式声明为已删除,因为"boost::intrusive::d etail::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的,还是我的错?

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

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