在我的带有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;
}