与操作符+进行枚举的boost :: intent冲突

时间:2018-10-09 14:52:00

标签: c++ boost-intrusive

在我的带有Boost 1.65.1.0ubuntu1的Ubuntu 18.04.1 LTS计算机上,以下代码

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// 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(trunk 339665)很好地编译,但是不能使用GCC 4.8.5、7.3.0、8.2.0和trunk进行编译。 这是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;
}

c语:

../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 个答案:

没有答案