From b1da5c25b4e91214a7983ddee6e328e3454b2e4f Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 10 Jan 2017 23:57:57 +0400 Subject: [PATCH] Fix compilation in case if key is void* If key type is `void*`, wrong `operator()` is chosen because of the dummy argument that is used for SFINAE. As a result the key comparison adapter invokes the user's predicate with only one argument, which fails to compile. Use a more distict type for SFINAE in the dummy arguments. Fixes ticket #12745. --- .../boost/intrusive/detail/key_nodeptr_comp.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/boost/intrusive/detail/key_nodeptr_comp.hpp b/include/boost/intrusive/detail/key_nodeptr_comp.hpp index 9d64f09..bdc025e 100644 --- a/include/boost/intrusive/detail/key_nodeptr_comp.hpp +++ b/include/boost/intrusive/detail/key_nodeptr_comp.hpp @@ -59,6 +59,10 @@ struct key_nodeptr_comp //Use public inheritance to avoid MSVC bugs with closures : public key_nodeptr_comp_types::base_t { +private: + struct sfinae_type; + +public: typedef key_nodeptr_comp_types types_t; typedef typename types_t::value_traits value_traits; typedef typename types_t::value_type value_type; @@ -83,32 +87,32 @@ struct key_nodeptr_comp //pred(pnode) template - BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible::value >::type* =0) const + BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const { return base().get()(key_of_value()(*traits_->to_value_ptr(t1))); } //operator() 2 arg //pred(pnode, pnode) template BOOST_INTRUSIVE_FORCEINLINE bool operator() - (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value >::type* =0) const + (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const { return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); } //pred(pnode, key) template BOOST_INTRUSIVE_FORCEINLINE bool operator() - (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value >::type* =0) const + (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const { return base()(*traits_->to_value_ptr(t1), t2); } //pred(key, pnode) template BOOST_INTRUSIVE_FORCEINLINE bool operator() - (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value >::type* =0) const + (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const { return base()(t1, *traits_->to_value_ptr(t2)); } //pred(key, key) template BOOST_INTRUSIVE_FORCEINLINE bool operator() - (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value >::type* =0) const + (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const { return base()(t1, t2); } const ValueTraits *const traits_;