c++ - 完善转发模板功能

标签 c++ c++11 perfect-forwarding

<分区>

我正在尝试实现一个通用函数,该函数记录另一个函数运行的时间。

#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 函数的模板类型。我做错了什么?

谢谢

最佳答案

代码中有几个问题。

先推导出函数返回类型:

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); });

关于c++ - 完善转发模板功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39353626/

相关文章:

c++ - 将参数与其他参数一起转发给构造函数

c# - 使用 Windows AES 加密提供程序在 C++ 中解密 C# 加密的数据

C++11 std::function 和完美转发

c++ - 如果需要,如何使用 Boost 库将具有可变数量参数的处理程序传递给类

c++ - Gnu C++ 什么时候会在不明确要求的情况下支持 C++11?

c++ - std::async 不使用 std::launch::async 策略启动新线程

C++ exponential_distribution模板类生成非精确随机数

c++ - 完美转发和 std::tuple

c++ - 在QT(C++)中实现简单鼓机的技巧

c++ - doxygen 文档 C++ header 中的当前日期