Trong MS Visual C++ 2010 SP1 mã này tai nạn:std :: chức năng bị treo khi sử dụng trong mảng trên stack
#include "stdafx.h"
#include <functional>
#include <iostream>
//#include <vector>
int a = 0;
int _tmain(int argc, _TCHAR* argv[]) {
// this way it works:
//std::vector<std::function<void()>> s;
//s.push_back([]() { a = 1; });
//s.push_back([]() { a = 2; int b = a; });
std::function<void()> s[] = {
[]() { a = 1; },
[]() {
a = 2;
// Problem occurs only if the following line is included. When commented out no problem occurs.
int b = a;
}
};
int counter = 0;
for (auto it = std::begin(s); it != std::end(s); ++it) {
++counter;
(*it)();
std::wcout << counter << L":" << a << std::endl;
}
return 0;
}
Khi phần tử mảng thứ hai được xây dựng nó corrupts phần tử mảng đầu tiên.
Đây có phải là lỗi trong trình biên dịch hay tôi đã làm điều gì đó không được hỗ trợ trong tiêu chuẩn C++ 11?
EDIT
Mã này hoạt động trong gcc-4.5.1:
#include <functional>
#include <iostream>
//#include <vector>
int a = 0;
int main(int argc, char* argv[]) {
// this way it works:
//std::vector<std::function<void()>> s;
//s.push_back([]() { a = 1; });
//s.push_back([]() { a = 2; int b = a; });
std::function<void()> s[] = {
[]() { a = 1; },
[]() {
a = 2;
// Problem occurs only if the following line is included.
//When commented out no problem occurs.
int b = a;
}
};
int counter = 0;
++counter;
s[0]();
std::wcout << counter << L":" << a << std::endl;
++counter;
s[1]();
std::wcout << counter << L":" << a << std::endl;
return 0;
}
Tôi không biết câu trả lời nhưng FWIW, hoạt động trên GCC 4.6 khi bạn đã loại bỏ các chi tiết cụ thể của MSVC. – Mat
Cảm ơn bạn đã thử nghiệm với GCC 4.6. Điều này cho một số bằng chứng cho một lỗi trong trình biên dịch MS. – frast
Các con trỏ đến các chức năng lambda được sai lầm trong thực tế, tôi hạn chế tối đa các vấn đề thành mã: #include #include int main (int argc, char * argv []) { \t std: : function s [] = { \t \t []() {std :: cout << "f0" << std :: endl;}, \t \t []() {int a = 1; std :: cout << "f1" << std :: endl;} \t}; \t s [0](); // đầu ra f1 thay vì f0 \t s [1](); // Điều này không thành công, con trỏ đến hàm có thể bị sai lệch trả về 0; } Khi bạn gọi s [0], nó ouput "f1" Và s [1] thực sự không thành công. –
Mesop