2011-09-02 20 views
6

Ví dụ sau đây chứng tỏ vấn đề tôi gặp phải trong VC++ 2010:Quy tắc tra cứu là gì khi gọi hàm từ lambda?

class Foo 
{ 
    template<class T> 
    static T foo(T t) { return t; } 

public: 
    void test() 
    { 
     auto lambda = []() { return foo(1); }; // call to Foo::foo<int> 
     lambda(); 
    } 
}; 

VC++ sản ​​xuất: lỗi C3861: 'foo': nhận dạng không tìm thấy

Nếu tôi đủ điều kiện cuộc gọi đến foo: Foo::foo(1); sau đó ví dụ này biên dịch với cảnh báo: Cảnh báo C4573: việc sử dụng 'Foo::foo' yêu cầu trình biên dịch bắt giữ 'this' nhưng chế độ chụp mặc định hiện tại không cho phép

Tiêu chuẩn nói gì về trường hợp này? Tên không đủ tiêu chuẩn được tìm thấy? Tên đủ điều kiện có yêu cầu chụp this không?

+0

Hm, thật kỳ lạ. Đó là tĩnh, vì vậy nó không nên yêu cầu 'này'. Tôi nghi ngờ đó là lỗi trình biên dịch và không tìm thấy nó là tác dụng phụ của trình biên dịch nghĩ rằng nó cần 'này' để sử dụng nó. –

+0

Điều này xảy ra với g ++ cũng vì vậy nó không có vẻ giống như một lỗi. Nếu bạn thay đổi nó thành [&]() thay vì []() thì điều này sẽ biên dịch tốt nhưng đó là bởi vì nó lấy điều này bằng cách tham chiếu. – DrYap

+0

Có nói rằng [thread khác] (http://stackoverflow.com/questions/4940259/c0x-lambdas-require-capturing-this-to-call-static-member-function) nói rằng đó là một lỗi. – DrYap

Trả lời

4

Microsoft đã gặp sự cố này được báo cáo trong một số trường hợp. Xem:

Scope Resolution with lambdas interferes with namespace and type resolution

Template resolution in lambdas

Như bạn đã phát hiện ra, độ phân giải rõ ràng cho phép nó để tìm tên. Có một cảnh báo bổ sung về điều này cũng là một lỗi trình biên dịch (độ phân giải tên không yêu cầu quyền truy cập vào điều này, mặc dù tôi có thể thấy cách thực hiện trình biên dịch có thể yêu cầu nó) - đó là một lỗi riêng biệt. Microsoft đã xác nhận đây là một lỗi và đã chuẩn bị một bản sửa lỗi cho bản phát hành tiếp theo.

2

Các biên dịch sau đây tốt. Dường như với tôi rằng đây chỉ là một lỗi VS với các mẫu.

struct Foo { 
    static void foo() {} 
    void bar() { 
     auto f = []() { foo(); }; 
     f(); 
    } 
}; 
+0

Bạn đã thử trình biên dịch nào? Có vẻ như kết quả khác nhau tùy thuộc vào trình biên dịch, vì vậy điều quan trọng là phải biết hành vi phù hợp tiêu chuẩn. –

+0

@Gene: VC++ 2010 đã triển khai lambdas trước [N2927] (http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2927.pdf), vì vậy, không phải * * phù hợp với từ ngữ của FDIS. – ildjarn

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