【问题标题】:How to use lambda in template definition in C++?如何在 C++ 的模板定义中使用 lambda?
【发布时间】:2015-12-19 17:11:10
【问题描述】:

这是我要实现的目标的一个简单示例。甚至可以将 lambda 传递给模板函数吗?

头文件

class my_impl {
public:
    template<typename F> void do_something(F && f);
};

CPP 文件

// .cpp file
template<typename F> my_impl::do_something(F && f)
{
    // ... implementation
}

template void my_impl::do_something<std::string &&>(std::string &&); // OK
template void my_impl::do_something<???>(???); // what goes here for lambda?

// used like this
my_impl impl;
impl.do_something( "123" );
impl.do_something( []() { 
   ...
} );

【问题讨论】:

  • Why can templates only be implemented in the header file?你已经可以用了,你要找的是如何显式实例化这个模板。
  • 您的示例代码中根本不需要 // OK// what goes here for lambda 行。删除它们并编译您的代码。请更清楚为什么你认为你需要它们。
  • @Yakk 注意这些在 .cpp 文件中。
  • 您是否尝试复制粘贴上面的示例代码,删除这两行并进行编译?同样,你仍然不需要这些行。我知道存在“附近”问题,您可能需要这些行,但发布实际存在问题的实际代码。在提交之前,将您的代码带回编译器并确保它仍然具有您想要的属性。伪代码在这里没用。
  • @Ragnar:你想为 lambda 写特化?!

标签: c++ templates lambda


【解决方案1】:

lambda 是唯一的、编译器生成的内部类型的实例。

您可以使用调试器亲自查看。例如,给定以下简短的测试代码 sn-p:

class my_impl {
public:
    template<typename F> void do_something(F && f);
};

template<typename F> void my_impl::do_something(F && f)
{
}

int main()
{
    my_impl m;

    m.do_something( []() {} );
}

使用 gcc 5.3,单步调试调试器,观察到以下结果:

main () at t.C:22
22      m.do_something( []() {} );
(gdb) s
my_impl::do_something<main()::<lambda()> >(<unknown type in /tmp/t, CU 0x0, DIE 0x23e>) (this=0x7fffffffe44d, f=<unknown type in /tmp/t, CU 0x0, DIE 0x23e>)
    at t.C:9

请注意,gdb 将模板实例报告为类型my_impl::do_something&lt;main()::&lt;lambda()&gt; &gt;。编译器为 lambda 类型生成了 main()::&lt;lambda()&gt; 的内部假类型。当然,你不能引用这样的类型。

我没有看到引用 lambda 内部类型的方法。

【讨论】:

    【解决方案2】:

    lambda 的类型取决于 lambda 本身。 你可以这样做

     auto l=[] (/*arguments*/) {/*body*/};
     template void my_impl::do_something<decltype(l)>(decltype(l)&&); 
    

    但这仅适用于 lambda l,因为编译器会为每个 lambda 生成新类型。

    可以像这样使用

    my_impl impl;
    impl.do_something(l);
    

    【讨论】:

    • 这适用于琐碎的羔羊。但我需要捕获类成员字段和一些局部变量,这些变量会根据使用情况而变化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多