如何在C++中的模板定义中使用lambda

How to use lambda in template definition in C++?

本文关键字:定义 lambda C++      更新时间:2023-10-16

下面是我试图实现的一个微不足道的例子。是否可以将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( []() { 
   ...
} );
lambda是唯一的、编译器生成的内部类型的实例。

您可以使用调试器亲眼看到这一点。例如,给定以下测试代码的短片段:

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<main()::<lambda()> >。编译器为lambda类型生成了一个内部伪类型main()::<lambda()>。当然,你不能引用这样的类型。

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

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