Почему в стандарте С++ 17 не были допущены аргументы с аргументами частного класса?

Одно из мест, на которых я надеялся, что смогу использовать новый вывод аргумента шаблона, заключался в создании 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), как можно найти:

Вычисление аргумента шаблона класса выполняется только в том случае, если список шаблонов шаблонов отсутствует. Если указан список аргументов шаблона, то дедукция не выполняется.

Каковы причины этого? Почему они не разрешили частичный вывод аргумента? Я думаю, есть некоторые проблемы с этим, что я упускаю из виду, но, на мой взгляд, это было бы более чем полезно.

Ответы

Ответ 1

В одной строке (С++ 17)

std::set s(std::initializer_list<int>{}, [](int a, int b) {return a > b; });

Ответ 2

В качестве альтернативы вы все равно можете сделать старый 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; });

Ответ 3

То, что вы должны делать, это написать тип функтора компаратора, поэтому вам не нужно прокси-сервера при использовании вашего набора. Это будет намного больше строк кода (зверство!), Но лучше практически во всех отношениях:

struct MyComparator
{
    bool operator()(int a, int b) const { ...; }
};
using MySet = std::set<int, MyComparator>;

И с этого момента вы просто создадите свой отсортированный набор, где вам это нужно.

Ответ 4

Из-за неоднозначности он приносит, когда присутствует параметр шаблона со значением по умолчанию. Кроме того, в случае вариационных шаблонов.