In C++14, associative containers seem to have changed from C++11 – [associative.reqmts]/13 says:
The member function templates
find
In C++11 there are not member templates find()
, lower_bound()
, etc. That is, nothing is lost by this change. The member templates were introduced with n3657 to allow heterogeneous keys being used with the associative containers. I don't see any concrete example where this is useful except for the example which is good and bad!
The is_transparent
use is intended to avoid unwanted conversions. If the member templates were unconstrained, existing code may pass through objects directly which would have been converted without the member templates. The example use-case from n3657 is locating an object in a std::set
using a string literal: with the C++11 definition a std::string
object is constructed when passing a string literals to the corresponding member function. With the change it is possible to use the string literal directly. If the underlying comparison function object is implemented exclusively in terms of std::string
that is bad because now a std::string
would be created for each comparison. On the other hand, if the underlying comparison function object can take a std::string
and a string literal, that may avoid construction of a temporary object.
The nested is_transparent
type in the comparison function object provides a way to specify if the templated member function should be used: if the comparison function object can deal with heterogeneous arguments, it defines this type to indicate that it can deal with different arguments efficiently. For example, the new operator function objects just delegate to operator<()
and claim to be transparent. That, at least, works for std::string
which has overloaded less than operators taking char const*
as argument. Since these function objects are also new, even if they do the wrong thing (i.e. require a conversion for some type) it would, at least, not be a silent change resulting in a performance degradation.