С++ принимает функцию в качестве шаблона и возвращает вектор возвращаемого типа функции

Я как раз экспериментировал с шаблонами C++, когда мой друг спросил меня о функции векторизации NumPy, поэтому я попытался реализовать свою собственную версию на C++. Однако я решил сделать так, чтобы исходная функция мгновенно вызывалась с помощью вектора, а не возвращалась векторизованная функция, поэтому я придумал такой код:

#include <iostream>
#include <vector>
#include <functional>
#include <type_traits>

using namespace std;

int f(int x) {
    return x + 5;
}

template<typename Func,
        typename Arg,
        typename Return = typename std::invoke_result_t<Func(Arg)>>
auto vectorizedCall(Func &func, std::vector<Arg> args) -> std::vector<Return> {
    std::vector<Return> resultVector;
    for(Arg a : args) {
        resultVector.push_back(func(a));
    }
    return resultVector;
}

int main(int argc, char *argv[]) {
    std::cout << f(5) << std::endl;
    std::vector<int> args{5, 6, 1, 4};
    auto vf = vectorizedCall(f, args);
    for (int32_t n : vf) {
        std::cout << n << std::endl;
    }
    return 0;
}

Но код не компилируется. Судя по всему, CLion сокращает очень-очень длинный лог ошибок до такого:

candidate template ignored: substitution failure [with Func = int (int), Arg = int]: function cannot return function type 'int (int)'

Однако я даже не пытаюсь вернуть тип функции. В чем здесь проблема и как ее решить?

Почему Func по ссылке?

πάντα ῥεῖ 12.12.2020 23:10
en.cppreference.com/w/cpp/types/result_of
chris 12.12.2020 23:11
invoke_result_t<F, Args...> не invoke_result_t<F(Args...)>
Barry 12.12.2020 23:14
std::transform делает то же самое, но использует итераторы.
alain 12.12.2020 23:16
std::vector<decltype(func(args.front()))> resultVector; и отбросить Return параметр и возвращаемый тип. Демо . Тем не менее - да, как говорит @alain, вы изобретаете заново std::transform
Igor Tandetnik 12.12.2020 23:18

Спасибо всем за ответы! Я знаю, что заново изобретаю std::transform, но, как я сказал в вопросе, я экспериментировал, и это даже близко не производственный код или какой-либо реальный код. Но, тем не менее, спасибо всем за ответы!

SM Melamed 13.12.2020 02:41
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Изменять

typename Return = typename std::invoke_result_t<Func(Arg)>>

к

typename Return = typename std::invoke_result_t<Func,Arg>>

И тебе должно быть хорошо идти!

Вы можете увидеть, как он работает онлайн по адресу: https://rextester.com/QMI86655

Другие вопросы по теме