What are transparent comparators?

前端 未结 4 674
无人共我
无人共我 2020-11-22 10:07

In C++14, associative containers seem to have changed from C++11 – [associative.reqmts]/13 says:

The member function templates find

4条回答
  •  旧时难觅i
    2020-11-22 10:35

    The following is all copy-pasta from n3657.

    Q. What is the purpose of making an comparator "transparent"?

    A. The associative container lookup functions (find, lower_bound, upper_bound, equal_range) only take an argument of key_type, requiring users to construct (either implicitly or explicitly) an object of the key_type to do the lookup. This may be expensive, e.g. constructing a large object to search in a set when the comparator function only looks at one field of the object. There is strong desire among users to be able to search using other types which are comparable with the key_type.

    Q. What problem does this solve

    A. The LWG had concerns about code like the following:

    std::set s = /* ... */;
    s.find("key");
    

    In C++11 this will construct a single std::string temporary and then compare it with elements to find the key.

    With the change proposed by N3465 the std::set::find() function would be an unconstrained template which would pass the const char* through to the comparator function, std::less, which would construct a std::string temporary for every comparison. The LWG considered this performance problem to be a serious issue. The template find() function would also prevent finding NULL in a container of pointers, which causes previously valid code to no longer compile, but this was seen as a less serious issue than the silent performance regression

    Q. does this change how standard containers work

    A. This proposal modifies the associative containers in and by overloading the lookup member functions with member function templates. There are no language changes.

    Q. so does the default set lose its find, count, etc. members

    A. Almost all existing C++11 code is unaffected because the member functions are not present unless new C++14 library features are used as the comparison functions.

    To quote Yakk,

    In C++14, std::set::find is a template function if Compare::is_transparent exists. The type you pass in does not need to be Key, just equivalent under your comparator.

    and n3657,

    Add paragraph 13 in 23.2.4 [associative.reqmts]: The member function templates find, lower_bound, upper_bound and equal_range shall not participate in overload resolution unless the type Compare::is_transparent does not exist does exist.

    n3421 provides an example of "Transparent Operator Functors".

    The full code is here.

提交回复
热议问题