Вывести тип шаблона из лямбда-вызова в контейнере - PullRequest
0 голосов
/ 04 августа 2020

У меня есть следующая реализация карты, которая принимает на вход вектор и лямбду и возвращает новый вектор.

template <typename R, typename T, typename Predicate>
std::vector<R> map(const std::vector<T> &v, Predicate p) {
    std::vector<R> mapd(v.size());
    std::transform(v.begin(), v.end(), mapd.begin(), p);
    return mapd;
}

Который я использую следующим образом

std::vector<int> input{1, 2, 3};
auto result = map<float>(input, [] (const int &v) { return v * 2.0; }); // result should be vector<float>{2., 4., 6.}

Это работает, но я хочу посмотреть, смогу ли я вывести тип шаблона R, не указывая его в вызове.

Теперь я знаю, что у меня есть как возвращаемый тип лямбда, так и тип входного вектора, Есть ли способ сделать это? Я пробовал использовать std::result_of_t<p(t)>, но ничего не нашел.

1 Ответ

2 голосов
/ 04 августа 2020

Вы имеете в виду следующее?

template <typename T, typename Predicate, 
          typename R = decltype(std::declval<Predicate>()(std::declval<T>()))>
std::vector<R> map(const std::vector<T> &v, Predicate p) {
    std::vector<R> mapd(v.size());
    std::transform(v.begin(), v.end(), mapd.begin(), p);
    return mapd;
}

Или может быть (если вы умеете использовать хотя бы C ++ 14)

template <typename T, typename Predicate>
auto map(const std::vector<T> &v, Predicate p) {
    std::vector<decltype(p(v[0]))> mapd(v.size());
    std::transform(v.begin(), v.end(), mapd.begin(), p);
    return mapd;
}
...