То, что я хочу достичь, является функцией makeSet(), принимающей три аргумента, пару итераторов и функцию, которая преобразует значение.использовать лямбда в функции шаблон, не могу вывести тип, makeSet() use case
Один случай использования может создавать набор из последовательности значений и не преобразование, например, преобразовать std::map<K,V>
в std::set<std::pair<V,K>>.
клиентский код может выглядеть
auto s = makeSet(hash.begin(), hash.end(),
[](std::pair<int,int> x) { return std::make_pair(x.second, x.first); });
моя текущая попытка, как следовать,
// (commented code are some other *failed* attempt).
template <typename Iterator,
typename T = typename std::iterator_traits<Iterator>::value_type,
template<typename ... > class Monad, typename R >
// typename R, typename Monad = std::function<R(T)> >
std::set<R> makeSet(Iterator first, Iterator last, Monad<R,T> f) {
std::set<R> res;
for (; first != last; ++first) res.insert(f(*first));
return res;
}
но, к сожалению, не работает. Проблема заключается в том, что не удалось найти R.
Есть ли решение или обходной путь? Буду очень признателен, если вы сможете сказать мне правильный способ сделать это.
О, любимый и когда-то придирчивый деклатип !! – qeatzy
Является ли диапазон средним объектом диапазона использования вместо пары итераторов, аналогичным [this] (https://ericniebler.github.io/std/wg21/D4128.html) или что-то другое? – qeatzy
Я бы просто использовал 'std :: decay_t', так как 'decay_t' делает типы подходящими для хранения. Второй момент заключается в том, что вы почти никогда не должны выводить тип 'std :: function'; 'std :: function' - класс типа стирания, а тип дедукции и стирание стилей - противоположности. Вывод того, какой тип стирать является признаком дизайнерского недостатка. Вы стираете, потому что здесь нужен фиксированный тип; вы выходите, потому что вы знаете точный тип здесь. Если вы знаете точный тип, 999/1000 раз вам не нужен фиксированный тип. –
Yakk