gpt4 book ai didi

c++ - 如何在声明和定义中拆分静态 lambda?

转载 作者:太空宇宙 更新时间:2023-11-04 15:30:26 26 4
gpt4 key购买 nike

我在类中有一个静态 lambda,它在头文件中声明和定义为:

class A final {
// inline could be removed of course for splitting
static inline auto foo = [](auto& param1, auto& param2 auto& param3) {
// do stuff
return;
}
}
// compiles fine

对于诸如 static int x = 42 之类的静态变量,我可以像这样拆分声明和定义:

// bar.h:
class Bar {
static int x;
}
// bar.cpp:
#include "bar.h"
int Bar::x = 42;

如何使用上述 lambda 来实现同样的事情?更改签名当然可以。

最佳答案

基本问题是每个 lambda 表达式都有自己单独的类型 ( see also this answer )。由于您需要知道声明变量的类型,并且需要知道 lambda 表达式才能知道其类型,因此在不知道 lambda 表达式本身的情况下,无法声明变量以保存 lambda 表达式的结果。

只要您知道两个地方的 lambda 表达式,就可以声明一个变量来保存您的 lambda 并分别定义该变量。例如:

inline auto makeFoo() {
return [](auto& param1, auto& param2, auto& param3) {
// do stuff
return;
};
}

class A final {
static decltype(makeFoo()) foo;
};

decltype(makeFoo()) A::foo = makeFoo();

但是,不可能将变量的声明与 lambda 表达式分开(即,您不能只在放置变量定义的文件中使用 lambda 表达式)。

不捕获任何内容的 lambda 表达式可以转换为指向函数的指针。如果您不需要 lambda 捕获任何东西(如您的示例)并且只需要一个特定签名的可调用对象,您可以简单地将 A::foo 声明为函数指针类型并初始化具有匹配 lambda 的 A::foo 的定义:

class A final {
static void (*foo)(int&, float&, double&);
};

void (*A::foo)(int&, float&, double&) = [](auto& param1, auto& param2, auto& param3) {
// do stuff
return;
};

如果您真的需要一个通用的 lambda(带有 auto 参数的),就像您的示例所建议的那样,那也行不通,您很可能不走运。拥有通用调用运算符意味着您的闭包类型的 operator () 函数必须是函数模板。拥有 operator () 函数模板意味着任何人都必须知道它的定义才能实际进行调用。即使您编写自己的类而不是使用 lambda 表达式,也无法让任何人在不知道其定义的情况下调用通用 operator ()。您所能做的就是为您需要支持的所有签名声明 operator () 模板的显式实例化,并分别定义它们。但是,这再次要求您实际上事先知道您需要可调用对象支持哪些具体签名……

关于c++ - 如何在声明和定义中拆分静态 lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54905053/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com