The following dummy example may not really make sense in real world. But it explains the question. I have a class Foo
with members firstname
and lastname
. The function ForEachMessage
takes a lambda. I want it to capture only the firstname
of Foo
but not lastname
. How do I achieve that?
#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;
}
You can use the C++14 named capture for this:
ForEachMessage([bla=firstname](const std::string& someMessage)
{
cout << bla << ": " << someMessage << endl;
});
(See it live) To avoid a copy, you may also capture by reference with [&bla=firstname]
instead. For a discussion on how to capture by const&
, see this question and in particular this answer.
(Remark: The local name can, but need not be different from the member name.)
Create a reference to firstname
const std::string& rfn = firstname;
And capture the reference
ForEachMessage([rfn](const std::string& someMessage)
{
cout << rfn << ": " << someMessage << endl;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With