libc ++对std :: map / set :: equal_range的实现产生了意外的结果

kov*_*val 6 c++ libc++

我注意到在clang的libc ++中std::set::equal_range(与相同std::map)给出的结果与libstdc ++不同。我一直认为equal_range应该返回std::make_pair(set.lower_bound(key), set.upper_bound(key))cppreference和libstdc ++所做的等效。但是在libc ++中,我有一个给出不同结果的代码。

#include <set>
#include <iostream>
#include <iterator>

struct comparator {
    using range_t = std::pair<int, int>;
    using is_transparent = std::true_type;
    bool operator()(int lhs, int rhs) const
    {
        return lhs < rhs;
    }
    bool operator()(int lhs, range_t rhs) const
    {
        return lhs < rhs.first;
    }
    bool operator()(range_t lhs, int rhs) const
    {
        return lhs.second < rhs;
    }
};

using range_set = std::set<int, comparator>;

int main()
{
    range_set set = { 1, 3, 6, 10 };
    auto range = comparator::range_t{2, 7};
    auto eq = set.equal_range(range);
    auto low = set.lower_bound(range);
    auto high = set.upper_bound(range);
    std::cout << "equal_range returned " << std::distance(eq.first, eq.second) << " elem(s): ";
    std::copy(eq.first, eq.second, std::ostream_iterator<int>(std::cout, " "));
    std::cout << "\nlower/upper returned " << std::distance(low, high) << " elem(s): ";
    std::copy(low, high, std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如你可以看到在https://rextester.com/CLTS82056这给

equal_range returned 1 elem(s): 3 
lower/upper returned 2 elem(s): 3 6 
Run Code Online (Sandbox Code Playgroud)

随着libstdc++以及与boost::container::set我得到在两种情况下2元(我希望)。

当然,我可以手动调用,lower_bound并且upper_bound在我的代码中使用equal_range,但是使用更短,可以清楚地表明我的意图(我想找到属于给定范围的所有元素)并且可能更快(因为equal_range方法可以被编码为一棵遍历树而无需实际调用到lower_boundupper_bound)。

有趣的是,std::multiset在这种情况下将容器类型更改为equal_rangereturn 2个元素。

现在这是一个bug libc++还是cppreference在https://en.cppreference.com/w/cpp/container/set/equal_range中给出了错误提示:

或者,可以使用获得第一个迭代器,而使用获得lower_bound()第二个迭代器upper_bound()

T.C*_*.C. 5

您的代码很好。

您正在过时的libc ++上进行测试。这是bug 30959,已在2018中修复并在clang 7中可用。

雷斯特的叮当声显然是3.8。