سؤال

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?

هل كانت مفيدة؟

المحلول

This looks like the same problem described at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53234

i.e. Boost 1.48 assumes the old behaviour of GCC 4.6, but GCC 4.7 was changed to implement the correct C++11 semantics regarding implicitly-defined copy/move constructors.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top