加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 05:53:23 所属栏目:百科 来源:网络整理
导读:请考虑以下代码: #include iostream#include functionalusing 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 functionvoid(int) h = f; h(2); // OK h(); // Error! How
请考虑以下代码:
#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的行为与f和g相同?

解决方法

std :: function有一个固定签名.这是一个设计选择,而不是一个艰巨的要求.编写支持多个签名的伪std ::函数并不困难:
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,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每个重载的单独副本.通过仔细的铸造,甚至可以有不同的羊皮不同的重量.

你可以写一个不这样做的,但它基本上需要重新实现std ::函数与一个鸽友的内部状态.

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

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

但是,这对于SO职位来说有点不好吗?

start of it

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读