【问题标题】:How do I capture some (but not all) member variables of a class with C++ lambda如何使用 C++ lambda 捕获类的一些(但不是全部)成员变量
【发布时间】:2016-06-14 06:08:21
【问题描述】:

以下虚拟示例在现实世界中可能没有真正意义。但它解释了这个问题。我有一个class Foo 成员firstnamelastname。函数 ForEachMessage 采用 lambda。我希望它只捕获Foofirstname 而不是lastname。我如何做到这一点?

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

vector<string> messagesList;
void ForEachMessage(function<void(const string&)>callBack)
{
    for (const auto& str : messagesList) {
        callBack(str);
    }
}

class Foo {
public:
    std::string firstname;
    std::string lastname;
    void say() {
        ForEachMessage([this](const std::string& someMessage)
        {
            cout << firstname << ": " <<  someMessage << endl;
        });

        // Error: firstname in capture list doesn't name a variable
        // ForEachMessage([firstname](const std::string& someMessage)
        // {
        //    cout << firstname << ": " <<  someMessage << endl;
        // });

        // Error: expect ',' or ']' in lambda capture list
        // ForEachMessage([this->firstname](const std::string& someMessage)
        // {
        //    cout << firstname << ": " <<  someMessage << endl;
        // });
    }
};

int main(int argc, const char * argv[]) {
    Foo foo;
    foo.firstname = "Yuchen";
    foo.lastname = "Zhong";
    messagesList.push_back("Hello, World!");
    messagesList.push_back("Byebye, World!");
    foo.say();
    return 0;
}

【问题讨论】:

  • “不起作用”是世界上最没用的问题描述。
  • @molbdnilo,感谢 cmets。我也添加了错误消息。
  • Quick fix。不知道是否有更好的方法。
  • 为了它的价值,挑选变量可能不值得付出努力。编译器可以很好地解决问题,并且不应该捕获 lambda 未使用的变量。
  • @BaummitAugen,这很有趣!

标签: c++


【解决方案1】:

您可以为此使用 C++14 命名捕获:

ForEachMessage([bla=firstname](const std::string& someMessage)
    {
        cout << bla << ": " <<  someMessage << endl;
    });

(查看live)为避免复制,您也可以使用[&amp;bla=firstname] 引用捕获。有关如何通过const&amp; 捕获的讨论,请参阅this question,尤其是this answer

(备注:本地名称可以,但不必与成员名称不同。)

【讨论】:

  • 看起来你甚至可以使用[&amp;firstname=firstname]
  • @SimonKraemer 确实,你秒杀我的编辑。谢谢输入。
  • @BaummitAugen 我刚刚测试了是否可以引用 const 以避免它在 lambda 中被更改。 [&amp;firstname=static_cast&lt;const string&amp;&gt;(firstname)] 完成这项工作。
【解决方案2】:

创建对firstname的引用

const std::string& rfn = firstname;

并捕获参考

ForEachMessage([rfn](const std::string& someMessage)
{
  cout << rfn << ": " << someMessage << endl;
}

【讨论】:

  • 糟糕。谢谢你修复我的。米(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多