У меня такой код:
#include <functional>
#include <memory>
#include <string>
#include <iostream>
struct A{
int i = 5;
};
class B{
std::unique_ptr<A> a;
std::function<void (void)> f;
public:
B(std::unique_ptr<A> a)
: a(std::move(a)),
f([&](){
std::cout << a->i << '\n'; //segfaults when executing a->i
})
{}
B()
: a(new A),
f([&](){
std::cout << a->i << '\n'; //works fine
})
{}
void execLambda(){
f();
}
void exec(){
std::cout << a->i << '\n'; //works fine
}
};
int main(){
B b1;
b1.exec(); //works fine
b1.execLambda(); //works fine
B b2(std::unique_ptr<A>(new A));
b2.exec(); //works fine
b2.execLambda(); //will segfault
return 0;
}
Кажется, когда объект заявляет о праве собственности на существующий unique_ptr и использует этот unique_ptr в лямбде, возникает ошибка сегментации. Почему в этом конкретном случае возникает ошибка сегментации? Есть ли способ использовать unique_ptr в лямбде, где было передано право собственности?
Большое спасибо!
1 ответ
Не называйте элементы и аргументы метода одним и тем же. Однако, если вы настаиваете на этом, вы сможете изменить лямбда-захват на [this]
вместо [&]
, чтобы решить проблему.
Как сказал комментатор:
Предположительно, я бы сказал, что лямбда захватывает a из конструктора - того, из которого вы переходите, а не из класса. - Джонатан Поттер
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .
a
из конструктора - того, из которого вы двигаетесь, а не того, что находится внутри класса.