Opened 5 years ago

Last modified 5 years ago

#13318 new Bugs

key_of_value now changes the type in the priority comparison for intrusive::treap_set

Reported by: Jan Martin Mikkelsen <janm@…> Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: intrusive
Version: Boost 1.65.0 Severity: Regression
Keywords: Cc:

Description

Setting the key_of_value option now changes the type used in the priority comparison, which makes it impossible to use key_of_value when the priority is entirely separate to the primary key.

The example below uses a comparison functor; a similar problem occurs with priority_compare(T const&, T const&) function.

This worked in 1.59, fails to compile in 1.65.1.

#include <boost/intrusive/treap_set.hpp>

using namespace boost::intrusive;

struct Test : public bs_set_base_hook<>
{
    Test(int k, int p) : m_key(k), m_priority(p) {}

    int m_key;
    int m_priority;
};

struct TestKey
{
    using type = int;
    int const& operator()(Test const& t) const { return t.m_key; }
};

struct PriorityCompare
{
    bool operator()(Test const& t1, Test const& t2) const {
	return t1.m_priority < t2.m_priority;
    }
};

using Container =
    treap_set<Test, key_of_value<TestKey>, priority<PriorityCompare>>;

int main()
{
    Test t1(1, 2);
    Container c;
    c.insert(t1);
}

Change History (1)

comment:1 by Jan Martin Mikkelsen <janm@…>, 5 years ago

For reference, this is the error message produced. The compiler is Clang from Xcode 9.

$ c++ -std=c++14 -I/usr/local/include/boost-1_65_1 test.cpp
In file included from test.cpp:1:
In file included from /usr/local/include/boost-1_65_1/boost/intrusive/treap_set.hpp:17:
In file included from /usr/local/include/boost-1_65_1/boost/intrusive/treap.hpp:28:
/usr/local/include/boost-1_65_1/boost/intrusive/priority_compare.hpp:46:14: error: 
      no matching function for call to 'priority_order'
      return priority_order(val, val2);
             ^~~~~~~~~~~~~~
/usr/local/include/boost-1_65_1/boost/intrusive/detail/tree_value_compare.hpp:90:14: note: 
      in instantiation of member function
      'boost::intrusive::priority_compare<int>::operator()' requested here
   {  return this->key_comp()(key1, KeyOfValue()(value2));  }
             ^
/usr/local/include/boost-1_65_1/boost/intrusive/detail/key_nodeptr_comp.hpp:110:14: note: 
      in instantiation of member function
      'boost::intrusive::tree_value_compare<Test *,
      boost::intrusive::priority_compare<int>, TestKey, false>::operator()'
      requested here
   {  return base()(t1, *traits_->to_value_ptr(t2));  }
             ^
/usr/local/include/boost-1_65_1/boost/intrusive/treap_algorithms.hpp:651:33: note: 
      in instantiation of function template specialization
      'boost::intrusive::detail::key_nodeptr_comp<boost::intrusive::priority_compare<int>,
      boost::intrusive::bhtraits<Test, boost::intrusive::tree_node_traits<void
      *>, boost::intrusive::link_mode_type::safe_link,
      boost::intrusive::dft_tag, 6>, TestKey>::operator()<int, const
      boost::intrusive::tree_node<void *> *>' requested here
      while(upnode != header && pcomp(k, upnode)){
                                ^
/usr/local/include/boost-1_65_1/boost/intrusive/treap_algorithms.hpp:493:10: note: 
      in instantiation of function template specialization
      'boost::intrusive::treap_algorithms<boost::intrusive::tree_node_traits<void
      *> >::rebalance_after_insertion_check<int,
      boost::intrusive::detail::key_nodeptr_comp<boost::intrusive::priority_compare<int>,
      boost::intrusive::bhtraits<Test, boost::intrusive::tree_node_traits<void
      *>, boost::intrusive::link_mode_type::safe_link,
      boost::intrusive::dft_tag, 6>, TestKey> >' requested here
         rebalance_after_insertion_check(header, commit_data.node, key, ...
         ^
/usr/local/include/boost-1_65_1/boost/intrusive/treap.hpp:662:28: note: in
      instantiation of function template specialization
      'boost::intrusive::treap_algorithms<boost::intrusive::tree_node_traits<void
      *> >::insert_unique_check<int,
      boost::intrusive::detail::key_nodeptr_comp<std::__1::less<int>,
      boost::intrusive::bhtraits<Test, boost::intrusive::tree_node_traits<void
      *>, boost::intrusive::link_mode_type::safe_link,
      boost::intrusive::dft_tag, 6>, TestKey>,
      boost::intrusive::detail::key_nodeptr_comp<boost::intrusive::priority_compare<int>,
      boost::intrusive::bhtraits<Test, boost::intrusive::tree_node_traits<void
      *>, boost::intrusive::link_mode_type::safe_link,
      boost::intrusive::dft_tag, 6>, TestKey> >' requested here
         (node_algorithms::insert_unique_check
                           ^
/usr/local/include/boost-1_65_1/boost/intrusive/treap.hpp:585:20: note: in
      instantiation of function template specialization
      'boost::intrusive::treap_impl<boost::intrusive::bhtraits<Test,
      boost::intrusive::tree_node_traits<void *>,
      boost::intrusive::link_mode_type::safe_link, boost::intrusive::dft_tag,
      6>, TestKey, void, void, unsigned long, true,
      void>::insert_unique_check<int, std::__1::less<int>,
      boost::intrusive::priority_compare<int> >' requested here
   {  return this->insert_unique_check(key, this->key_comp(), this->priv...
                   ^
/usr/local/include/boost-1_65_1/boost/intrusive/treap.hpp:499:45: note: in
      instantiation of member function
      'boost::intrusive::treap_impl<boost::intrusive::bhtraits<Test,
      boost::intrusive::tree_node_traits<void *>,
      boost::intrusive::link_mode_type::safe_link, boost::intrusive::dft_tag,
      6>, TestKey, void, void, unsigned long, true, void>::insert_unique_check'
      requested here
      std::pair<iterator, bool> ret = this->insert_unique_check(key_of_v...
                                            ^
/usr/local/include/boost-1_65_1/boost/intrusive/treap_set.hpp:240:25: note: in
      instantiation of member function
      'boost::intrusive::treap_impl<boost::intrusive::bhtraits<Test,
      boost::intrusive::tree_node_traits<void *>,
      boost::intrusive::link_mode_type::safe_link, boost::intrusive::dft_tag,
      6>, TestKey, void, void, unsigned long, true, void>::insert_unique'
      requested here
   {  return tree_type::insert_unique(value);  }
                        ^
test.cpp:37:7: note: in instantiation of member function
      'boost::intrusive::treap_set_impl<boost::intrusive::bhtraits<Test,
      boost::intrusive::tree_node_traits<void *>,
      boost::intrusive::link_mode_type::safe_link, boost::intrusive::dft_tag,
      6>, TestKey, void, void, unsigned long, true, void>::insert' requested
      here
    c.insert(t1);
      ^
/usr/local/include/boost-1_65_1/boost/intrusive/priority_compare.hpp:32:6: note: 
      candidate function template not viable: requires 0 arguments, but 2 were
      provided
void priority_order();
     ^
1 error generated.

Note: See TracTickets for help on using tickets.