Boost Intrusive's unordered_set is broken if you do a vanilla install of Fedora 17 which comes with GCC 4.7 and Boost 1.48, and use C++11 mode. On Fedora 16, which comes with GCC 4.6.2 and Boost 1.47, it works. This breaks real code, and it even breaks the example in the 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
}
The error message:
/usr/include/boost/intrusive/hashtable.hpp:227:65: error: use of deleted function ‘constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost::intrusive::detail::bucket_traits_impl >::type>&)’
In file included from /usr/include/boost/intrusive/hashtable.hpp:30:0, from /usr/include/boost/intrusive/unordered_set.hpp:18, from t.cpp:23:
/usr/include/boost/intrusive/detail/hashtable_node.hpp:80:8: note: ‘constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost::intrusive::detail::bucket_traits_impl >::type>&)’ is implicitly declared as deleted because ‘boost::intrusive::detail::bucket_traits_impl >::type>’ declares a move constructor or move assignment operator
Here is the code it refers to, hashtable.hpp:227:
template<class BucketTraits>
bucket_plus_size(BOOST_FWD_REF(BucketTraits) b_traits)
: bucket_traits_(::boost::forward<BucketTraits>(b_traits))
{}
In Boost 1.47, this was:
bucket_plus_size(const bucket_traits &b_traits)
: bucket_traits_(b_traits)
{}
BOOST_FWD_REF(TYPE)
on my system is defined as TYPE &&
by default, but if BOOST_NO_RVALUE_REFERENCES
is defined then it becomes const TYPE &
. And if I do define it that way, the code compiles!
Any thoughts on why this is? Is it GCC's fault, Boost's, Fedora's, or mine?