Какую проблему это решает,
См ответ Дитмар в и ответ remyabel в .
и меняет ли это принцип работы стандартных контейнеров?
Нет, не по умолчанию.
Новые перегрузки шаблонов функций-членов findи т. Д. Позволяют использовать тип, сопоставимый с ключом контейнера, вместо использования самого типа ключа. См. N3465 Хоакина Му Лопеса Муньоса для обоснования и подробного, тщательно написанного предложения по добавлению этой функции.
На встрече в Бристоле LWG согласилась, что функция гетерогенного поиска полезна и желательна, но мы не могли быть уверены, что предложение Хоакина будет безопасным во всех случаях. Предложение N3465 вызвало бы серьезные проблемы для некоторых программ (см. Раздел « Влияние на существующий код »). Хоакин подготовил обновленный черновой вариант предложения с некоторыми альтернативными реализациями с разными компромиссами, что было очень полезно, помогая LWG понять плюсы и минусы, но все они рисковали каким-то образом нарушить некоторые программы, поэтому не было единого мнения о добавлении этой функции. Мы решили, что, хотя добавлять эту функцию безоговорочно было бы небезопасно, было бы безопасно, если бы она была отключена по умолчанию и была только «включаться».
Ключевым отличием предложения N3657 (которое было доработкой в последнюю минуту мной и STL на основе N3465 и более позднего неопубликованного проекта Хоакина) было добавление is_transparentтипа в качестве протокола, который можно использовать для выбора новой функциональности.
Если вы не используете «прозрачный функтор» (т.е. тот, который определяет is_transparentтип), тогда контейнеры будут вести себя так же, как и всегда, и это по-прежнему по умолчанию.
Если вы решите использовать std::less<>(что является новым для C ++ 14) или другой тип «прозрачного функтора», вы получите новую функциональность.
Использование std::less<>легко с помощью шаблонов псевдонимов:
template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
using set = std::set<T, Cmp, Alloc>;
Название is_transparentпроисходит от STL N3421, который добавил «алмазные операторы» в C ++ 14. «Прозрачный функтор» - это тот, который принимает любые типы аргументов (которые не обязательно должны быть одинаковыми) и просто перенаправляет эти аргументы другому оператору. Такой функтор оказывается именно тем, что вам нужно для гетерогенного поиска в ассоциативных контейнерах, поэтому этот тип is_transparentбыл добавлен ко всем операторам ромба и использовался как тип тега, чтобы указать, что новые функции должны быть включены в ассоциативных контейнерах. Технически контейнерам не нужен «прозрачный функтор», только тот, который поддерживает его вызов с разнородными типами (например, pointer_compтип в https://stackoverflow.com/a/18940595/981959 не является прозрачным согласно определению STL,pointer_comp::is_transparentпозволяет использовать его для решения проблемы). Если вы когда-либо выполняете поиск только std::set<T, C>с ключами типа Tили intтогда Cнужно вызывать только аргументы типа Tи int(в любом порядке), это не обязательно должно быть действительно прозрачным. Мы использовали это имя отчасти потому, что не смогли придумать лучшего имени (я бы предпочел, is_polymorphicпотому что такие функторы используют статический полиморфизм, но уже есть std::is_polymorphicхарактеристика типа, которая относится к динамическому полиморфизму).