Kode berikut dikompilasi dengan gcc 4.5.1 tetapi tidak dengan VS2010 SP1:
#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <set>
#include <algorithm>
using namespace std;
class puzzle
{
vector<vector<int>> grid;
map<int,set<int>> groups;
public:
int member_function();
};
int puzzle::member_function()
{
int i;
for_each(groups.cbegin(),groups.cend(),[grid,&i](pair<int,set<int>> group){
i++;
cout<<i<<endl;
});
}
int main()
{
return 0;
}
Ini kesalahannya:
error C3480: 'puzzle::grid': a lambda capture variable must be from an enclosing function scope
warning C4573: the usage of 'puzzle::grid' requires the compiler to capture 'this' but the current default capture mode does not allow it
Begitu,
1> kompiler mana yang benar?
2> Bagaimana saya bisa menggunakan variabel anggota di dalam lambda di VS2010?
c++
visual-studio-2010
lambda
c++11
vivek
sumber
sumber
pair<const int, set<int> >
, itulah tipe pasangan sebenarnya dari peta. Mungkin juga harus menjadi referensi-ke-const.Jawaban:
Saya percaya VS2010 benar kali ini, dan saya akan memeriksa apakah saya memiliki standar yang berguna, tetapi saat ini saya tidak.
Sekarang, persis seperti pesan kesalahan mengatakan: Anda tidak dapat menangkap hal-hal di luar cakupan melampirkan lambda. †
grid
tidak ada dalam lingkup terlampir, tetapithis
(setiap akses untukgrid
benar - benar terjadi sepertithis->grid
dalam fungsi anggota). Untuk penggunaan kami, menangkapthis
karya, karena Anda akan segera menggunakannya dan Anda tidak ingin menyalinnyagrid
Namun, jika Anda ingin menyimpan kisi dan menyalinnya untuk akses nanti, di mana
puzzle
objek Anda mungkin sudah dihancurkan, Anda harus membuat salinan lokal menengah:† Saya menyederhanakan - Google untuk "jangkauan" atau lihat §5.1.2 untuk semua detail berdarah.
sumber
tmp
menjadiconst &
untukgrid
untuk mengurangi menyalin? Kami masih menginginkan setidaknya satu salinan, salinan ke lambda ([tmp]
), tetapi tidak perlu salinan kedua.grid
meskipun mungkin dioptimalkan. Lebih pendek dan lebih baik adalah:auto& tmp = grid;
dll.[grid = grid](){ std::cout << grid[0][0] << "\n"; }
untuk menghindari salinan tambahanerror: capture of non-variable ‘puzzle::grid’
Ringkasan alternatif:
tangkap
this
:gunakan referensi lokal untuk anggota:
C ++ 14:
contoh: https://godbolt.org/g/dEKVGD
sumber
[&grid]
masih tidak bekerja). Sangat senang mengetahui hal ini!Saya percaya, Anda perlu menangkap
this
.sumber
grid
. Masalahnya, bagaimana jika Anda ingin menyalin kotak? Ini tidak akan memungkinkan Anda untuk melakukan itu.Metode alternatif yang membatasi ruang lingkup lambda daripada memberikannya akses ke keseluruhan
this
adalah dengan memberikan referensi lokal ke variabel anggota, misalnyasumber