完善转发模板功能
Perfect forwarding a template function
我正在尝试实现一个通用函数,该函数记录另一个函数花费多长时间 运行。
#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <functional>
#include <numeric>
#include <memory>
template<typename Res, typename Func, typename...Args>
std::pair<Res, double> ftime(Func fun, Args&&... args)
{
auto start = std::chrono::system_clock::now();
Res res = fun(std::forward<Args>(args)...);
std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
return std::make_pair(res, duration.count());
}
int main ()
{
std::vector<int> values (100, 1);
auto res = ftime(std::accumulate, values.begin(), values.end(), 0);
std::cout << "Sum up " << values.size() << std::endl;
std::cout << "Serial sum = " << res.first << " took : " << res.second << std::endl;
}
以上代码编译失败,出现以下错误:
sum_1000000.cpp: In function ‘int main()’:
sum_1000000.cpp:22:68: error: no matching function for call to ‘ftime(<unresolved overloaded function type>, std::vector<int>::iterator, std::vector<int>::iterator, int)’
auto res = ftime(std::accumulate, values.begin(), values.end(), 0);
^
sum_1000000.cpp:10:24: note: candidate: template<class Res, class Func, class ... Args> std::pair<Res, double> ftime(Func, Args&& ...)
std::pair<Res, double> ftime(Func fun, Args&&... args)
^
sum_1000000.cpp:10:24: note: template argument deduction/substitution failed:
sum_1000000.cpp:22:68: note: couldn't deduce template parameter ‘Res’
auto res = ftime(std::accumulate, values.begin(), values.end(), 0);
据我所知,编译器无法识别 std::acumulate 函数的模板类型。我做错了什么?
谢谢
代码中有几个问题。
推导函数return 先输入:
template<typename Func, typename...Args>
auto ftime(Func fun, Args&&... args) -> std::pair<decltype(fun(std::forward<Args>(args)...)), double>
{
auto start = std::chrono::system_clock::now();
auto res = fun(std::forward<Args>(args)...);
std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
return std::make_pair(res, duration.count());
}
std::accumulate
不是一个函数,而是一个模板。最简单的方法是将调用包装到 lambda 中:
auto res = ftime([&values]() { return std::accumulate(values.begin(), values.end(), 0); });
编译器无法推断出您模板的 Res
,也无法推断出 accumulate
.
的模板参数
#include <utility>
#include <chrono>
#include <vector>
#include <numeric>
#include <iostream>
template<typename Func, typename...Args>
auto invoke_timed(Func&& fun, Args&&... args) ->
std::pair<decltype(std::forward<Func>(fun)(std::forward<Args>(args)...)),
std::chrono::system_clock::duration::rep>
{
auto start = std::chrono::system_clock::now();
auto res = std::forward<Func>(fun)(std::forward<Args>(args)...);
return std::make_pair(res, (std::chrono::system_clock::now() - start).count());
}
int main()
{
std::vector<int> values(100, 1);
auto res = invoke_timed(std::accumulate<std::vector<int>::iterator, int>,
values.begin(), values.end(), 0);
std::cout << res.first << ", " << res.second << "\n";
return 0;
}
我正在尝试实现一个通用函数,该函数记录另一个函数花费多长时间 运行。
#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <functional>
#include <numeric>
#include <memory>
template<typename Res, typename Func, typename...Args>
std::pair<Res, double> ftime(Func fun, Args&&... args)
{
auto start = std::chrono::system_clock::now();
Res res = fun(std::forward<Args>(args)...);
std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
return std::make_pair(res, duration.count());
}
int main ()
{
std::vector<int> values (100, 1);
auto res = ftime(std::accumulate, values.begin(), values.end(), 0);
std::cout << "Sum up " << values.size() << std::endl;
std::cout << "Serial sum = " << res.first << " took : " << res.second << std::endl;
}
以上代码编译失败,出现以下错误:
sum_1000000.cpp: In function ‘int main()’:
sum_1000000.cpp:22:68: error: no matching function for call to ‘ftime(<unresolved overloaded function type>, std::vector<int>::iterator, std::vector<int>::iterator, int)’
auto res = ftime(std::accumulate, values.begin(), values.end(), 0);
^
sum_1000000.cpp:10:24: note: candidate: template<class Res, class Func, class ... Args> std::pair<Res, double> ftime(Func, Args&& ...)
std::pair<Res, double> ftime(Func fun, Args&&... args)
^
sum_1000000.cpp:10:24: note: template argument deduction/substitution failed:
sum_1000000.cpp:22:68: note: couldn't deduce template parameter ‘Res’
auto res = ftime(std::accumulate, values.begin(), values.end(), 0);
据我所知,编译器无法识别 std::acumulate 函数的模板类型。我做错了什么?
谢谢
代码中有几个问题。
推导函数return 先输入:
template<typename Func, typename...Args>
auto ftime(Func fun, Args&&... args) -> std::pair<decltype(fun(std::forward<Args>(args)...)), double>
{
auto start = std::chrono::system_clock::now();
auto res = fun(std::forward<Args>(args)...);
std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
return std::make_pair(res, duration.count());
}
std::accumulate
不是一个函数,而是一个模板。最简单的方法是将调用包装到 lambda 中:
auto res = ftime([&values]() { return std::accumulate(values.begin(), values.end(), 0); });
编译器无法推断出您模板的 Res
,也无法推断出 accumulate
.
#include <utility>
#include <chrono>
#include <vector>
#include <numeric>
#include <iostream>
template<typename Func, typename...Args>
auto invoke_timed(Func&& fun, Args&&... args) ->
std::pair<decltype(std::forward<Func>(fun)(std::forward<Args>(args)...)),
std::chrono::system_clock::duration::rep>
{
auto start = std::chrono::system_clock::now();
auto res = std::forward<Func>(fun)(std::forward<Args>(args)...);
return std::make_pair(res, (std::chrono::system_clock::now() - start).count());
}
int main()
{
std::vector<int> values(100, 1);
auto res = invoke_timed(std::accumulate<std::vector<int>::iterator, int>,
values.begin(), values.end(), 0);
std::cout << res.first << ", " << res.second << "\n";
return 0;
}