Возвращает тип лямбды в C ++ 11 изнутри лямбда (функция плоской карты)

Я реализовал функцию, вдохновленную на плоской карте scala, и мне интересно, смогу ли я получить доступ к типу возврата лямбды внутри лямбды, чтобы не повторять его при использовании

/**
* Inspired on scala's flat map, provide a @param func which output will be flattened in the output
* sequence, which is the return type of @param func
*/
template <typename IN, typename F>
auto flat_mapf(const IN& input, F func)
-> decltype(func(std::declval<typename IN::value_type>()))
{
decltype(func(std::declval<typename IN::value_type>())) output;
auto outit = std::back_inserter(output);
for (auto i = input.begin(); i != input.end(); ++i)
{
decltype(func(std::declval<typename IN::value_type>())) interm = func(*i);
std::move(interm.begin(), interm.end(), outit);
}
return output;
}// usage example, I would like to avoid repeating vector<size_t> type two times:
auto vo = flat_mapf(vi, [](const size_t& x) -> vector<size_t> {
vector<size_t> res;
for (size_t i = 0; i < x; ++i)
res.push_back(x);
return res;
});

3

Решение

Не могли бы вы просто опустить -> vector<size_t> из примера использования, поэтому компилятор выводит тип возврата лямбда? Таким образом, вы говорите только один раз.

0

Другие решения

Поскольку функциональность, которую вы хотите предоставить, работает на диапазонах (что очень разумно), я могу указать вам на Boost.Range. Пользователь сможет объединить ваши flat_mapf например, с boost::irange вот так:

auto vo = flat_mapf(vi, [](size_t x) {
return boost::irange(size_t { 0 }, x);
});

(boost::irange работает только над целыми типами, boost::counting_range является более общим.)

0

Возвращение фактического вектора может быть неправильным подходом. Это требует, чтобы все выходные данные каждого элемента создавались и кэшировались до того, как они будут собраны вместе.

Шаблон генератора некоторого вида, такой как функтор вложенной карты, который возвращает опциональное повышение (пустой означает законченное создание) или тому подобное, означал бы, что вам не потребуется промежуточный контейнер. Превратить такой генератор в вектор std легко, и написание плоской карты, когда каждая из субкарт является лямбда-генератором, также легко.

Я поднимаю это, потому что это также означает, что спецификация двойного типа исчезает. В ситуациях, когда тринарный оператор не работает, у вас есть только одно местоположение, которое возвращает, а другое — пустое.

Короче говоря, вы, возможно, часто набираете std vector, потому что вы делаете много std векторов.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector