Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top