Ответ 1
В одной строке (С++ 17)
std::set s(std::initializer_list<int>{}, [](int a, int b) {return a > b; });
Одно из мест, на которых я надеялся, что смогу использовать новый вывод аргумента шаблона, заключался в создании std::set
/std::map
/любых других контейнеров с пользовательскими компараторами - моя цель - создать однострочный оператор, который создаст эффективный набор с помощью лямбда-компаратора. Что я могу сделать, так как С++ 11:
std::set<int, std::function<bool(int, int)>> s([](int a, int b) {return a > b;});
Но поскольку он использует std::function
, он заметно медленнее.
Другой вариант:
auto mycomp = [](int a, int b) {return a > b; };
std::set<int, decltype(mycomp)> s(mycomp);
Он выполняет свою работу, но 1) Он требует 2 строки и создание переменной mycomp
2) Мне нужно явно передать тип mycomp
.
Когда я читаю на справочных страницах, ни один из стандартных контейнеров не имеет руководства по вычитанию для такого рода ситуаций. К сожалению, я боюсь, что этого не может быть даже сделано с текущим стандартом языка (С++ 17), как можно найти:
Вычисление аргумента шаблона класса выполняется только в том случае, если список шаблонов шаблонов отсутствует. Если указан список аргументов шаблона, то дедукция не выполняется.
Каковы причины этого? Почему они не разрешили частичный вывод аргумента? Я думаю, есть некоторые проблемы с этим, что я упускаю из виду, но, на мой взгляд, это было бы более чем полезно.
В одной строке (С++ 17)
std::set s(std::initializer_list<int>{}, [](int a, int b) {return a > b; });
В качестве альтернативы вы все равно можете сделать старый make_xxx
template <typename T, typename COMP>
std::set<T, COMP> make_set(COMP comp)
{
return std::set<T, COMP>{comp};
}
auto s = make_set<int>([](int a, int b) {return a > b; });
То, что вы должны делать, это написать тип функтора компаратора, поэтому вам не нужно прокси-сервера при использовании вашего набора. Это будет намного больше строк кода (зверство!), Но лучше практически во всех отношениях:
struct MyComparator
{
bool operator()(int a, int b) const { ...; }
};
using MySet = std::set<int, MyComparator>;
И с этого момента вы просто создадите свой отсортированный набор, где вам это нужно.
Из-за неоднозначности он приносит, когда присутствует параметр шаблона со значением по умолчанию. Кроме того, в случае вариационных шаблонов.