O
Size: a a a
O
BB
Е
O
BB
AS
this
, переданный в лямбду, становится невалиден. Вызов переданной лямбды делается таким образом:template<typename... Args>
void call_impl(Args&&... args) const
{
QMetaObject::invokeMethod(
context,
[this, args = std::tuple(std::forward<Args>(args)...)]() mutable {
std::apply(callback, std::move(args));
},
Qt::ConnectionType::QueuedConnection);
}
context
в данном случае — это QAbstractEventDispatcher*
, я его получаю через QAbstractEventDispatcher::instance();
однократно при создании моего объекта.std::apply(callback, std::tuple(std::forward<Args>(args)...));
исправляет падение, но я не очень понимаю, в какую сторону дальше копать в поисках причины. Е
this
, переданный в лямбду, становится невалиден. Вызов переданной лямбды делается таким образом:template<typename... Args>
void call_impl(Args&&... args) const
{
QMetaObject::invokeMethod(
context,
[this, args = std::tuple(std::forward<Args>(args)...)]() mutable {
std::apply(callback, std::move(args));
},
Qt::ConnectionType::QueuedConnection);
}
context
в данном случае — это QAbstractEventDispatcher*
, я его получаю через QAbstractEventDispatcher::instance();
однократно при создании моего объекта.std::apply(callback, std::tuple(std::forward<Args>(args)...));
исправляет падение, но я не очень понимаю, в какую сторону дальше копать в поисках причины. O
move
и forward
для args
имеют одинаковое поведение и я, честно говоря, даже забыл про эту строкуЕ
move
и forward
для args
имеют одинаковое поведение и я, честно говоря, даже забыл про эту строкуAS
move
и forward
для args
имеют одинаковое поведение и я, честно говоря, даже забыл про эту строку#include <string>
#include <iostream>
template<typename T>
void eat(T&&) {
}
template<typename T>
void foo(T&& t) {
eat(std::move(t));
}
int main() {
std::string s{"123456678901234566789012345667890"};
foo(s);
// что выведется в консоль?
std::cout << s;
}
O
#include <string>
#include <iostream>
template<typename T>
void eat(T&&) {
}
template<typename T>
void foo(T&& t) {
eat(std::move(t));
}
int main() {
std::string s{"123456678901234566789012345667890"};
foo(s);
// что выведется в консоль?
std::cout << s;
}
AS
O
std::forward<decltype(args)>(args)
AS
std::forward<decltype(args)>(args)
O
QEventLoop e;
// Так же может быть MyClass или MyClass&&
// но никогда не MyClass&, ибо это не будет работать
Async<MyClass> async = [&](MyClass const&s){
std::cout << "In lambda: " << s << std::endl; //
e.quit();
};
MyClass f{"42"};
async(f); // Вызывается один конструктор копирования
async(MyClass{"42"}); // Вызывается один оператор перемещения
tuple
, переданным в лямбдуO
QEventLoop e;
// Так же может быть MyClass или MyClass&&
// но никогда не MyClass&, ибо это не будет работать
Async<MyClass> async = [&](MyClass const&s){
std::cout << "In lambda: " << s << std::endl; //
e.quit();
};
MyClass f{"42"};
async(f); // Вызывается один конструктор копирования
async(MyClass{"42"}); // Вызывается один оператор перемещения
tuple
, переданным в лямбдуstd::tuple
, дальше уже у меня либо лежит копия, которую можно мувать без боязни, либо объект, в который мы только что смували, разрушив оригинальный rvalueBB
#include <string>
#include <iostream>
template<typename T>
void eat(T&&) {
}
template<typename T>
void foo(T&& t) {
eat(std::move(t));
}
int main() {
std::string s{"123456678901234566789012345667890"};
foo(s);
// что выведется в консоль?
std::cout << s;
}