【问题标题】:Lambdas and passing a pointer class as argumentLambdas 并将指针类作为参数传递
【发布时间】:2016-06-28 06:03:12
【问题描述】:

我在将类指针作为参数传递给 lambdas 回调时遇到问题。

粘贴箱:http://pastebin.com/SqXHtGDt

我如何定义回调:

typedef void (*cb_prescription)(Prescription * prescription);

我如何使用回调:

void loop_prescriptions (cb_prescription callback, bool add = true)
{
    for (int i = 1; i <= prescriptions->noOfElements(); i++) {
        Prescription * prescription = (Prescription *) prescriptions->removeNo(i);
        if (add) {
            prescriptions->add(prescription);
        }
        callback(prescription);
    }
}

我知道一切正常,除了参数指针部分。

loop_prescriptions ([&] (Prescription * paper) { paper->something(); });

我得到的错误:

错误:无法将“list_prescriptions_by_doctor()::”转换为“cb_prescription {aka void ()(Prescription*)}”,以将参数“1”转换为“void loop_prescriptions(cb_prescription, bool)” });*

有人知道我是如何错误地使用参数的吗? 我尝试将指针的引用添加为 *&,然后删除指针,但是 List 类(是的,我必须使用它)返回一个类指针,所以我不能简单地使用副本。

感谢您的帮助!

更新 我已经根据答案更新了我的 pastebin,它提供了一个可行的解决方案。 http://pastebin.com/7yTPGEQx

【问题讨论】:

  • 您不能将有状态的 lambda(捕获任何内容)转换为函数指针。这就是错误所说的。要么不使用(非全局)状态,要么修改loop_prescriptions 签名。
  • 所以我需要事先将我需要的任何参数传递到 lambda 范围内?
  • 不,如果你打算使用你的回调类型和所有使用该回调类型的类,你必须使用无上下文的 lambdas。或者,如果您需要该上下文,则需要相应地更改回调类型。
  • 是否可以使用两个 lambda?一个是我定义 char 指针名称(作为配置 lambda),另一个是我将处理处方的 lambda? pastebin.com/PF8AZgrp

标签: c++ class pointers c++11 lambda


【解决方案1】:

你的函数只接受函数指针,而你正在传递一个 lambda(或者换句话说,任何随机类)。由于类不是函数指针,因此很可能希望接受函子(例如,所有类似函数的东西)

我猜您可以通过 2 种不同的方式更改您的代码:

// Using a std::function object; which wraps both function pointers and classes with () operator
using cb_prescription = std::function<void(Prescription*)>;

template<typename cb_prescription>
void loop_prescriptions (cb_prescription &&callback, bool add = true)

第一个变体是我更喜欢的变体,因为它非常通用,不幸的是它带有包装回调的性能开销。除非你是性能关键代码,否则我会使用这个。

第二个变体通过模板工作,所以你传递的任何东西都可以用 () 运算符和匹配的参数调用。但是,它要求所有调用者都可以使用此代码。由于模板,function-ptr, lambda 的确切类型是已知的,因此您不会从 std::function 获得开销。

【讨论】:

  • 尝试添加 #include &lt;functional&gt; 并使用正确的 lambda 语法´[](){}´ PS:不要使用 auto_ptr,它已被弃用,请改用 std::unique_ptr
  • 有什么想法可以修改它以使其与不同的类名一起使用吗?使用回调 = std::functionvoid>;
猜你喜欢
  • 1970-01-01
  • 2021-12-18
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2020-11-08
  • 2020-09-13
相关资源
最近更新 更多