2016-03-01 17 views
5

Ví dụ giả sau đây có thể không thực sự có ý nghĩa trong thế giới thực. Nhưng nó giải thích câu hỏi. Tôi có một số class Foo với các thành viên firstnamelastname. Hàm ForEachMessage lấy một lambda. Tôi muốn nó chỉ chụp firstname của Foo nhưng không chỉ chụp lastname. Làm thế nào để đạt được điều đó?Làm cách nào để chụp một số biến thành viên (nhưng không phải tất cả) của một lớp với C++ lambda

#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; 
} 
+1

"Không hoạt động" là mô tả sự cố hữu ích nhất trên thế giới. – molbdnilo

+0

@molbdnilo, cảm ơn nhận xét. Tôi cũng đã thêm thông báo lỗi. –

+1

[Sửa nhanh] (http://coliru.stacked-crooked.com/a/131b92770d94e458). Tự hỏi nếu có một cách tốt hơn mặc dù. –

Trả lời

5

Bạn có thể sử dụng C++ 14 tên chụp cho điều này:

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

(Xem nó live) Để tránh một bản sao, bạn cũng có thể chụp bằng cách tham chiếu với [&bla=firstname] để thay thế. Để thảo luận về cách chụp bằng const&, hãy xem this question và cụ thể là this answer.

(Ghi chú: Tên địa phương có thể, nhưng không khác với tên thành viên.)

+0

Bây giờ, điều này thật thú vị! – Nard

+2

Có vẻ như bạn thậm chí có thể sử dụng '[& firstname = firstname]' –

+0

@SimonKraemer Thật vậy, bạn đã đánh bại bản chỉnh sửa của tôi theo giây.Thx cho dữ liệu nhập. –

3

Tạo một tham chiếu đến firstname

const std::string& rfn = firstname; 

Và chụp tài liệu tham khảo

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

Cảm ơn bạn đã chỉnh sửa! – Nard

+0

Rất tiếc. Cảm ơn vì đã sửa mỏ. M ( –

Các vấn đề liên quan