Пользователь хочет передать копию, но он заблокирован инкапсуляцией библиотеки [&]
, здесь coliru MCVE : -
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <functional>
int main(){
std::vector<std::function<void()>> funcs;
for(int n=0;n<3;n++){
auto func=[&,n](){ //[=] for n
std::cout<<""<<n; // user's code
};
//v library (actually inside another utility function)
funcs.push_back([&](){ //user's "n" is blocked ??
//(some library-related code here)
func();
});
//^ library
}
//v library
for(int n=0;n<3;n++){
funcs[n]();
}
}
Он печатает 222
вместо012
.
Почему и как обойти это?
Обратите внимание, что библиотека не может знать о n
.
Согласно связанному вопросу ( c ++ лямбда-захватпо значению ) значение должно быть скопировано правильно.
Вот более сложный MCVE , который делает то же самое, но может лучше показать, как я на самом деле его использую: -
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <functional>
std::vector<std::function<void()>> libraryStuff;
template<class F>void addToLibrary(F f){
libraryStuff.push_back([&](){ //user's "n" is blocked ??
//some code library related
f();
});
}
void libraryDoNow(){
for(int m=0;m<libraryStuff.size();m++){
libraryStuff[m]();
}
}
int main(){
std::vector<std::function<void()>> funcs;
for(int n=0;n<3;n++){
auto func=[&,n](){
std::cout<<""<<n; // user's code
};
addToLibrary(func);
}
libraryDoNow();
}