Я как раз экспериментировал с шаблонами 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)'
Однако я даже не пытаюсь вернуть тип функции. В чем здесь проблема и как ее решить?
invoke_result_t<F, Args...>
не invoke_result_t<F(Args...)>
std::transform
делает то же самое, но использует итераторы.
std::vector<decltype(func(args.front()))> resultVector;
и отбросить Return
параметр и возвращаемый тип. Демо . Тем не менее - да, как говорит @alain, вы изобретаете заново std::transform
Спасибо всем за ответы! Я знаю, что заново изобретаю std::transform, но, как я сказал в вопросе, я экспериментировал, и это даже близко не производственный код или какой-либо реальный код. Но, тем не менее, спасибо всем за ответы!
Изменять
typename Return = typename std::invoke_result_t<Func(Arg)>>
к
typename Return = typename std::invoke_result_t<Func,Arg>>
И тебе должно быть хорошо идти!
Вы можете увидеть, как он работает онлайн по адресу: https://rextester.com/QMI86655
Почему
Func
по ссылке?