Use of string_view for map lookup

后端 未结 1 1847
名媛妹妹
名媛妹妹 2020-12-09 14:31

The following code fails to build on recent compilers (g++-5.3, clang++-3.7).

#include 
#include 
#include 

        
相关标签:
1条回答
  • 2020-12-09 15:15

    You need to specify a transparent comparator explicitly (like std::less<>):

    std::map<std::string, int, std::less<>> m;
    //                         ~~~~~~~~~~^
    

    std::map<K,V> defaults its comparator to std::less<K> (i.e., a non-transparent one), and since ([associative.reqmts]/p13):

    The member function templates find, count, lower_bound, upper_bound, and equal_range shall not participate in overload resolution unless the qualified-id Compare::is_transparent is valid and denotes a type (14.8.2).

    the template member function find is not a viable candidate.

    Heterogeneous comparison lookup for associative containers was added to c++14. The original proposal risked breaking existing code. For example:

    c.find(x);
    

    is semantically equivalent to:

    key_type key = x;
    c.find(key);
    

    In particular, the conversion between x and key_type happens only once, and before the actual call.

    Heterogenous lookup replaces this conversion in favour of a comparison between key and x. This may lead to a drop in performance in existing code (due to addtional conversion before each comparison) or even break compilation (if the comparison operator is a member function, it will not apply conversion for a left-hand side operand):

    #include <set>
    #include <functional>
    
    struct A
    {
        int i;
    
        A(int i) : i(i) {}
    };
    
    bool operator<(const A& lhs, const A& rhs)
    {
        return lhs.i < rhs.i;
    }
    
    int main()
    {
        std::set<A, std::less<>> s{{1}, {2}, {3}, {4}};
        s.find(5);
    }
    

    DEMO

    To resolve this the new behaviour was made opt-in by adding the concept of transparent comparators as described in the linked question.

    0 讨论(0)
提交回复
热议问题