Home:ALL Converter>Discrepencies between std::lower_bound and std::set::lower_bound

Discrepencies between std::lower_bound and std::set::lower_bound

Ask Time:2011-09-21T01:02:59         Author:Mooing Duck

Json Formatter

The C++ draft says about std::lower_bound:

§ 25.4.3.1 lower_bound [lower.bound]  
template<class ForwardIterator, class T>  
ForwardIterator lower_bound(ForwardIterator first, 
                            ForwardIterator last, 
                            const T& value);  
template<class ForwardIterator, class T, class Compare>  
ForwardIterator lower_bound(ForwardIterator first, 
                            ForwardIterator last, 
                            const T& value, 
                            Compare comp);  

Requires: The elements e of [first,last) shall be partitioned with respect 
    to the expression e < value or comp(e, value).
Returns: The furthermost iterator i in the range [first,last] such that for 
    any iterator j in the range [first,i) the following corresponding 
    conditions hold: *j < value or comp(*j, value) != false.
Complexity: At most log2(last − first) + O(1) comparisons.

Note that this allows (by implication) one to compare a different (but comparable) type than *ForwardIterator would return, but there's no complexity limitation on the number of iterator advancements. (For a node based container, this would be O(last − first) iterator advancements.)

§ 23.4.6.1
class set { 
   ...
    iterator lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
   ...
}

The standard doesn't detail these functions, but it's implied that these are for O(log2(last − first)) comparisons and advancements, but require the search key to be the same as the contained type.

So my questions are:
(1) Is there a way to get the speed of std::set::lower_bound and the flexibility of search type of std::lower_bound?
(2) Why isn't std::lower_bound required to be specialized for std::set::iterator?
(3) Are there implementations where std::lower_bound is specialized for std::set::iterator, or is there a reason why not?

I was hoping to find something like:

template< class Key, class Comp, class Alloc, class Lookup>  
std::set<Key, Compare, Alloc>::const_iterator 
    lower_bound(
        std::set<Key, Comp, Alloc>::const_iterator begin, 
        std::set<Key, Comp, Alloc>::const_iterator end, 
        const Lookup& find,
        Compare comp);
template< class Key, class Comp, class Alloc, class Lookup>  
std::set<Key, Compare, Alloc>::iterator 
    lower_bound(
        std::set<Key, Comp, Alloc>::iterator begin, 
        std::set<Key, Comp, Alloc>::iterator end, 
        const Lookup& find,
        Compare comp);

or:

template < class Key, class Compare = less<Key>, class Allocator = allocator<Key> >
class set {
   ...
    template<class Lookup>
    iterator lower_bound(const Lookup& x);
    template<class Lookup>
    const_iterator lower_bound(const Lookup& x) const;
   ...
}

But I doubt it exists. Obviously, all of this can be expanded to other tree-based containers, and other algorithms. I'd code it myself, but it would require me to use implementation specific code. This idea came from this question: Efective search in set with non-key type

Author:Mooing Duck,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/7488896/discrepencies-between-stdlower-bound-and-stdsetlower-bound
yy