boost :: intrusive clash с оператором + для перечисления

На моей машине Ubuntu 18.04.1 LTS с boost 1.65.1.0ubuntu1, следующий код

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// container.h

#include <boost/intrusive/list.hpp>
#include <boost/intrusive/rbtree.hpp>

namespace bi = boost::intrusive;

struct Item
{
/// Metadata container for the list "view"bi::list_member_hook<> list_hook_;

int payload;

};

//Define a list that will store Items
using ListOption = bi::member_hook<
Item, bi::list_member_hook<>, &Item::list_hook_>;
using ItemList = bi::list<Item, ListOption>;struct Container {
ItemList lru;
};

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// enum_ops.h

#include <type_traits>

/** Add an int to an enum
*
* @param val enum value
* @param step increment (integer)
* @return the next enum value
*
* This allows testing::Range to be used with enumerated types
* (Range uses the expression @code value_ = value_ + step_ @endcode,
* where value_ would be the enumerated type and step_ would be @c int).
*/
template <typename E>
constexpr typename std::enable_if<std::is_enum<E>::value, E>::type
operator+(E val, int step)
{
return static_cast<E>(static_cast<int>(val) + step);
}

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

int main()
{
Container c;
return 0;
}

прекрасно компилируется с clang 4.0, 6.0 и clang версии 8.0.0 (транк 339665), но не компилируется с GCC 4.8.5, 7.3.0, 8.2.0 и транком.
Вот вывод из GCC 8.2.0:

In file included from /usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:42,
from /usr/include/boost/intrusive/list.hpp:26,
from ../prog/sxld/src/enum_pilot.cc:4:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp: In instantiation of ‘const int boost::intrusive::function_detector::DetectMember_InstantiationKey_to_node_ptr<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, boost::intrusive::list_node<void*>* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(Item&), boost::intrusive::list_node<void*>* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(Item&) const, boost::intrusive::list_node<void*>* (*)(Item&)>::check’:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:64:11:   required from ‘const bool boost::intrusive::detail::is_stateful_value_traits<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_> >::value’
/usr/include/boost/intrusive/detail/iiterator.hpp:79:22:   required from ‘const bool boost::intrusive::iiterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true, std::bidirectional_iterator_tag>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:42:22:   required from ‘const bool boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:128:79:   required from ‘class boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>’
/usr/include/boost/intrusive/list.hpp:741:22:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear_and_dispose(Disposer) [with Disposer = boost::intrusive::detail::null_disposer; ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:719:10:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:246:16:   required from ‘boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::~list_impl() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:1441:7:   required from here
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:44:1: error: ambiguous overload for ‘operator+’ (operand types are ‘boost::intrusive::function_detector::<unnamed enum>’ and ‘long unsigned int’)
BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:44:1: note: candidate: ‘operator+(int, long unsigned int)’ <built-in>
../prog/sxld/src/enum_pilot.cc:45:1: note: candidate: ‘constexpr typename std::enable_if<std::is_enum<_Tp>::value, E>::type operator+(E, int) [with E = boost::intrusive::function_detector::<unnamed enum>; typename std::enable_if<std::is_enum<_Tp>::value, E>::type = boost::intrusive::function_detector::<unnamed enum>]’
operator+(E val, int step)
^~~~~~~~
In file included from /usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:42,
from /usr/include/boost/intrusive/list.hpp:26,
from ../prog/sxld/src/enum_pilot.cc:4:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp: In instantiation of ‘const int boost::intrusive::function_detector::DetectMember_InstantiationKey_to_value_ptr<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, Item* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(boost::intrusive::list_node<void*>*), Item* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(boost::intrusive::list_node<void*>*) const, Item* (*)(boost::intrusive::list_node<void*>*)>::check’:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:67:11:   required from ‘const bool boost::intrusive::detail::is_stateful_value_traits<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_> >::value’
/usr/include/boost/intrusive/detail/iiterator.hpp:79:22:   required from ‘const bool boost::intrusive::iiterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true, std::bidirectional_iterator_tag>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:42:22:   required from ‘const bool boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:128:79:   required from ‘class boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>’
/usr/include/boost/intrusive/list.hpp:741:22:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear_and_dispose(Disposer) [with Disposer = boost::intrusive::detail::null_disposer; ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:719:10:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:246:16:   required from ‘boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::~list_impl() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:1441:7:   required from here
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:45:1: error: ambiguous overload for ‘operator+’ (operand types are ‘boost::intrusive::function_detector::<unnamed enum>’ and ‘long unsigned int’)
BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:45:1: note: candidate: ‘operator+(int, long unsigned int)’ <built-in>
../prog/sxld/src/enum_pilot.cc:45:1: note: candidate: ‘constexpr typename std::enable_if<std::is_enum<_Tp>::value, E>::type operator+(E, int) [with E = boost::intrusive::function_detector::<unnamed enum>; typename std::enable_if<std::is_enum<_Tp>::value, E>::type = boost::intrusive::function_detector::<unnamed enum>]’
operator+(E val, int step)
^~~~~~~~
In file included from /usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:42,
from /usr/include/boost/intrusive/list.hpp:26,
from ../prog/sxld/src/enum_pilot.cc:4:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp: In instantiation of ‘const int boost::intrusive::function_detector::DetectMember_InstantiationKey_to_node_ptr<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, const boost::intrusive::list_node<void*>* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(const Item&), const boost::intrusive::list_node<void*>* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(const Item&) const, const boost::intrusive::list_node<void*>* (*)(const Item&)>::check’:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:70:11:   required from ‘const bool boost::intrusive::detail::is_stateful_value_traits<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_> >::value’
/usr/include/boost/intrusive/detail/iiterator.hpp:79:22:   required from ‘const bool boost::intrusive::iiterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true, std::bidirectional_iterator_tag>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:42:22:   required from ‘const bool boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:128:79:   required from ‘class boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>’
/usr/include/boost/intrusive/list.hpp:741:22:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear_and_dispose(Disposer) [with Disposer = boost::intrusive::detail::null_disposer; ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:719:10:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:246:16:   required from ‘boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::~list_impl() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:1441:7:   required from here
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:44:1: error: ambiguous overload for ‘operator+’ (operand types are ‘boost::intrusive::function_detector::<unnamed enum>’ and ‘long unsigned int’)
BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:44:1: note: candidate: ‘operator+(int, long unsigned int)’ <built-in>
../prog/sxld/src/enum_pilot.cc:45:1: note: candidate: ‘constexpr typename std::enable_if<std::is_enum<_Tp>::value, E>::type operator+(E, int) [with E = boost::intrusive::function_detector::<unnamed enum>; typename std::enable_if<std::is_enum<_Tp>::value, E>::type = boost::intrusive::function_detector::<unnamed enum>]’
operator+(E val, int step)
^~~~~~~~
In file included from /usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:42,
from /usr/include/boost/intrusive/list.hpp:26,
from ../prog/sxld/src/enum_pilot.cc:4:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp: In instantiation of ‘const int boost::intrusive::function_detector::DetectMember_InstantiationKey_to_value_ptr<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, const Item* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(const boost::intrusive::list_node<void*>*), const Item* (boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>::*)(const boost::intrusive::list_node<void*>*) const, const Item* (*)(const boost::intrusive::list_node<void*>*)>::check’:
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:73:11:   required from ‘const bool boost::intrusive::detail::is_stateful_value_traits<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_> >::value’
/usr/include/boost/intrusive/detail/iiterator.hpp:79:22:   required from ‘const bool boost::intrusive::iiterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true, std::bidirectional_iterator_tag>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:42:22:   required from ‘const bool boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>::stateful_value_traits’
/usr/include/boost/intrusive/detail/list_iterator.hpp:128:79:   required from ‘class boost::intrusive::list_iterator<boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>, true>’
/usr/include/boost/intrusive/list.hpp:741:22:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear_and_dispose(Disposer) [with Disposer = boost::intrusive::detail::null_disposer; ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:719:10:   required from ‘void boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::clear() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:246:16:   required from ‘boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::~list_impl() [with ValueTraits = boost::intrusive::mhtraits<Item, boost::intrusive::list_member_hook<>, &Item::list_hook_>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void]’
/usr/include/boost/intrusive/list.hpp:1441:7:   required from here
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:45:1: error: ambiguous overload for ‘operator+’ (operand types are ‘boost::intrusive::function_detector::<unnamed enum>’ and ‘long unsigned int’)
BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/intrusive/detail/is_stateful_value_traits.hpp:45:1: note: candidate: ‘operator+(int, long unsigned int)’ <built-in>
../prog/sxld/src/enum_pilot.cc:45:1: note: candidate: ‘constexpr typename std::enable_if<std::is_enum<_Tp>::value, E>::type operator+(E, int) [with E = boost::intrusive::function_detector::<unnamed enum>; typename std::enable_if<std::is_enum<_Tp>::value, E>::type = boost::intrusive::function_detector::<unnamed enum>]’
operator+(E val, int step)
^~~~~~~~

Какая семья компиляторов подходит?

Этот код отклонен всеми компиляторами:

// operator+ as above
enum Stooges { Larry, Curly, Moe };

int main()
{
Stooges l = Larry;
auto moe = l + 2ul;
return moe;
}

лязг говорит:

../prog/sxld/src/enum_pilot.cc:58:15: error: use of overloaded operator '+' is ambiguous (with operand types 'Stooges' and 'unsigned long')
auto moe = l + 2ul;
~ ^ ~~~
../prog/sxld/src/enum_pilot.cc:46:1: note: candidate function [with E = Stooges]
operator+(E val, int step)
^
../prog/sxld/src/enum_pilot.cc:58:15: note: built-in candidate operator+(int, unsigned long)
auto moe = l + 2ul;
^

Этот код принят всеми компиляторами:

// operator+ as above
enum class Stooges { Larry, Curly, Moe };

int main()
{
Stooges l = Stooges::Larry;
auto moe = l + 2ul;
return moe == Stooges::Moe;
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector