0

The following code using Boost 1.72.0:

#include <iostream>
#include <string>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>

struct Foo
{
    int intProp_;
    std::string stringProp_;
};

template<typename T>
struct LoggingLess
{
    auto operator()(const T& first, const T& second) const
    {
        std::cout << "Comparing '" << first << "' to '" << second << "'\n";
        return std::less<T>()(first, second);
    }
};

int main()
{
    using namespace boost::multi_index;

    typedef multi_index_container<Foo, indexed_by<
        ordered_non_unique<member<Foo, int, &Foo::intProp_>>,
        ordered_non_unique<member<Foo, std::string, &Foo::stringProp_>, LoggingLess<std::string>>
    >> FooContainer;

    FooContainer container;

    container.insert({ 1, "xyz" });
    container.insert({ 2, "abc" });

    std::cout << "Insert finished\n";

    auto& intIndex = container.get<0>();
    intIndex.modify_key(intIndex.begin(), [](int& value)
        {
            value += 100;
        });
}

Has the following output:

Comparing 'abc' to 'xyz'
Insert finished
Comparing 'xyz' to 'abc'

Given that I'm only updating the integer value used in the first index, why does boost multi_index also compare the strings? This could have important performance implications on keys such as strings.

Is it a simple oversight or some limitation of the implementation?

D. Jurcau
  • 190
  • 6
  • Whereas in your case, you know that changing int property doesn't change order for string, it is not easy to track, especially with custom comparer. – Jarod42 Jan 01 '20 at 13:16

1 Answers1

1

There is no documented guarantee in any API you are using that editing a key cannot change the order of other indexes.

So boost does not assume it.

It guarantees that if your operation does not change the order with respect to other keys, it will be O(1) in container size. But it will validate this, whih is what you are seeing; that requires up to 2 comparisons for each ordered key.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524