Can we use a heterogeneous comparison comparator to perform a “partial match” search in STL associative containers?

So, I was looking for support for heterogeneous searches in STL associative containers (starting with C ++ 14) and got a little confused about what we can do and what is not worth it. Next snippet

#include <algorithm>
#include <iostream>
#include <set>

struct partial_compare : std::less<>
{
    //"full" key_type comparison done by std::less
    using less<>::operator();

    //"sequence-partitioning" comparison: only check pair first member
    bool operator ()(std::pair<int, int> const &lhs, int rhs) const
    {
        return lhs.first < rhs;
    }

    bool operator ()(int lhs, std::pair<int, int> const &rhs) const
    {
        return lhs < rhs.first;
    }
};

int main()
{
    //Using std::set lookup
    {
        std::cout << "std::set equal_range:\n";
        std::set <std::pair<int, int>, partial_compare> s{{1,0},{1,1},{1,2},{1,3},{2,0}};

        auto r = s.equal_range (1);

        for (auto it = r.first; it != r.second; ++it)
        {
            std::cout << it->first << ", " << it->second << '\n';
        }

        std::cout << "std::set lower_bound + iteration on equivalent keys:\n";
        auto lb = s.lower_bound(1);

        while (lb != std::end(s) && !s.key_comp()(lb->first, 1) && !s.key_comp()(1, lb->first))
        {
            std::cout << lb->first << ", " << lb->second << '\n';
            ++lb;
        }
    }

    //Using algorithms on std::set
    {
        std::cout << "std::equal_range\n";
        std::set <std::pair<int, int>> s{{1,0},{1,1},{1,2},{1,3},{2,0}};

        auto r = std::equal_range (std::begin(s), std::end(s), 1, partial_compare{});
        for (auto it = r.first; it != r.second; ++it)
        {
            std::cout << it->first << ", " << it->second << '\n';
        }
    }
    return 0;
}

Produces the following output when compiling with clang-5 / libC ++:

std::set equal_range:
1, 1
std::set lower_bound + iteration on equivalent keys:
1, 0
1, 1
1, 2
1, 3
std::equal_range
1, 0
1, 1
1, 2
1, 3

And when compiling with gcc-7.1.0:

std::set equal_range:
1, 0
1, 1
1, 2
1, 3
std::set lower_bound + iteration on equivalent keys:
1, 0
1, 1
1, 2
1, 3
std::equal_range
1, 0
1, 1
1, 2
1, 3

N3465, , , , , : " " , " ".
, , , N3657, , , , "" , , "is_transparent".
, , std:: set equal_range clang/lib++ gcc "lower_bound + scan". - ( clang , equal_range lower_bound + scan UB) clang/lib++?

EDIT: lib++.
equal_range lib++ libstd++
SO, .
, , , , .

+6
1

lib++: equal_range ( r315179) "" .

+6

All Articles