Какую проблему это решает,
См ответ Дитмар в и ответ 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
характеристика типа, которая относится к динамическому полиморфизму).