【问题标题】:Passing lambda to template function将 lambda 传递给模板函数
【发布时间】:2015-10-25 23:43:11
【问题描述】:

我有以下代码:

template <typename L>
double measure( L&& action )
{
    using namespace std::chrono;

    high_resolution_clock::time_point start, end;
    duration<double> timeSpan;

    start = high_resolution_clock::now();
    action();
    end = high_resolution_clock::now();

    timeSpan = duration_cast<milliseconds>(end - start);
    return timeSpan.count();
}

我是这样使用它的:

    cout << measure([](){ mergeSort<float>(array, 0, 10000); }) << endl << endl;

到目前为止,这是我知道传递 lambda 函数的唯一方法。但是,我试图让这个函数更完整,允许传递一个 ratio 作为模板参数,指定 timeSpan 模板的 ratio,以毫秒以外的其他度量返回时间......

所以,我想知道如何将多个模板参数传递给一个函数并一起传递一个 lambda。我应该在模板上指定什么作为 lambda 的类型,或者我还能做些什么来实现这样的目标:

    timer::measure<ratio<1,1000>>([](){ mergeSort<float>(array, 0, 10000); })

?

【问题讨论】:

  • 模板参数std::ratio&lt;1, 1000&gt;如何在measure中使用?
  • 函数的倒数第二行是timeSpan = duration_cast&lt;duration&lt;double, RATIO&gt;&gt;(end - start);

标签: c++ templates lambda


【解决方案1】:

你可以有这样的东西:

template <typename Ratio, typename L>
//        ^^^^^^^^^^^^^^^^
double measure( L&& action )
{
    using namespace std::chrono;

    auto start = high_resolution_clock::now();
    action();
    auto end = high_resolution_clock::now();

    auto timeSpan = duration_cast<duration<double, Ratio>>(end - start);
    //                            ^^^^^^^^^^^^^^^^^^^^^^^
    return timeSpan.count();
}

Live demo

【讨论】:

  • g++ 在我尝试过这个时给了我一个很长的错误输出。再次尝试检查我是否输入错误,但没有。 g++ 基本上抱怨这个:note: template argument deduction/substitution failed:
  • @PedroVernetti Cannot reproduce。如果您忘记使用measure&lt;ratio&lt;1,1000&gt;&gt; 更新对measure 的调用,这听起来像是一个错误that would happen
  • 没有。真的不是这样。我已经完全按照我的建议输入了。
  • @PedroVernetti 你能提供一个关于这个错误的SSCCE吗?
  • 在缩短代码向您展示时,我意识到duration_cast&lt; ... 中缺少“>”,对不起。当你说我可能忘记更新通话时,我只检查了通话..
【解决方案2】:

首先,传递lambda函数的标准方法是使用std:function

#include <functional>

...

double measure( std::function<void()> action ){
    ...
}

然后以你使用的方式使用它

cout << measure([&](){ mergeSort<float>(array, 0, 10000); }) << endl << endl;

然后,您可以通过删除模板参数 L 来应用 Jefffrey 的答案。

【讨论】:

  • “标准”,即存储 lambda 函数的推荐方式是std::function。相比之下,当传递时,在接收端使用函数模板会更好,因为这样做避免了std::function...本身就是一个模板的额外开销无论如何,但是有一堆额外的膨胀来启用类型擦除,在这种情况下这不是必需的。见stackoverflow.com/questions/14677997
猜你喜欢
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多