gpt4 book ai didi

c++ - 将具有默认参数的 lambda 函数复制到变量

转载 作者:可可西里 更新时间:2023-11-01 15:51:59 25 4
gpt4 key购买 nike

考虑以下代码:

#include <iostream>
#include <functional>
using namespace std;

int main() {
auto f = [](int a = 3) {cout << a << endl; };
f(2); // OK
f(); // OK

auto g = f;
g(2); // OK
g(); // OK

function<void(int)> h = f;
h(2); // OK
h(); // Error! How to make this work?

return 0;
}

如何声明 h 的行为与 fg 相同?

最佳答案

std::function 有一个固定的签名。这是一个设计选择,而不是硬性要求。编写支持多个签名的伪 std::function 并不难:

template<class...Sigs>
struct functions;

template<>
struct functions<> {
functions()=default;
functions(functions const&)=default;
functions(functions&&)=default;
functions& operator=(functions const&)=default;
functions& operator=(functions&&)=default;
private:
struct never_t {private:never_t(){};};
public:
void operator()(never_t)const =delete;

template<class F,
std::enable_if_t<!std::is_same<std::decay_t<F>, functions>{}, int>* =nullptr
>
functions(F&&) {}
};

template<class S0, class...Sigs>
struct functions<S0, Sigs...>:
std::function<S0>,
functions<Sigs...>
{
functions()=default;
functions(functions const&)=default;
functions(functions&&)=default;
functions& operator=(functions const&)=default;
functions& operator=(functions&&)=default;
using std::function<S0>::operator();
using functions<Sigs...>::operator();
template<class F,
std::enable_if_t<!std::is_same<std::decay_t<F>, functions>{}, int>* =nullptr
>
functions(F&& f):
std::function<S0>(f),
functions<Sigs...>(std::forward<F>(f))
{}
};

使用:

auto f = [](int a = 3) {std::cout << a << std::endl; };

functions<void(int), void()> fs = f;
fs();
fs(3);

Live example .

这将为每个重载创建一个单独的 lambda 拷贝。通过仔细的转换,甚至可以为不同的重载使用不同的 lambda。

你可以写一个不这样做的,但它基本上需要用更高级的内部状态重新实现 std::function

上面的更高级版本将避免使用线性继承,因为这会导致 O(n^2) 代码和 O(n) 签名数量的递归模板深度。平衡二叉树继承将其降低到生成 O(n lg n) 代码和 O(lg n) 深度。

工业强度版本将存储传入的 lambda 一次,使用小对象优化,具有使用二进制继承策略分派(dispatch)函数调用的手动伪 vtable,并将分派(dispatch)函数指针存储在所述伪 vtable 中.它将在每个类(而不是每个实例)的基础上占用 O(# signatures)*sizeof(function pointer) 空间,并且使用与 std::function 一样多的每个实例开销.

但这对于 SO 帖子来说有点过分了,不是吗?

start of it

关于c++ - 将具有默认参数的 lambda 函数复制到变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37715137/

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