Как создать функцию std :: function из лямбда-выражения захвата движения?
Я пытаюсь создатьstd::function
из захвата движения лямбда-выражения. Обратите внимание, что я могу без проблем создать лямбда-выражение захвата движения; это только когда я пытаюсь обернуть его вstd::function
что я получаю ошибку.
Например:
auto pi = std::make_unique<int>(0);
// no problems here!
auto foo = [q = std::move(pi)] {
*q = 5;
std::cout << *q << std::endl;
};
// All of the attempts below yield:
// "Call to implicitly-deleted copy constructor of '<lambda...."
std::function<void()> bar = foo;
std::function<void()> bar{foo};
std::function<void()> bar{std::move(foo)};
std::function<void()> bar = std::move(foo);
std::function<void()> bar{std::forward<std::function<void()>>(foo)};
std::function<void()> bar = std::forward<std::function<void()>>(foo);
Я объясню, почему я хочу написать что-то подобное. Я написал библиотеку пользовательского интерфейса, которая, подобно jQuery или JavaFX, позволяет пользователю обрабатывать события мыши / клавиатуры, передаваяstd::function
с методами с именами, такими какon_mouse_down()
, on_mouse_drag()
, push_undo_action()
, так далее.
Очевидно, чтоstd::function
Я хочу передать, в идеале следует использовать лямбда-выражение захвата движения, в противном случае мне нужно прибегнуть к уродливой идиоме «release / acqu-in-lambda», которую я использовал, когда C ++ 11 был стандартом:
std::function<void()> baz = [q = pi.release()] {
std::unique_ptr<int> p{q};
*p = 5;
std::cout << *q << std::endl;
};
Обратите внимание, что вызовbaz
дважды будет ошибкой в приведенном выше коде. Однако в моем коде это закрытие гарантированно будет вызвано ровно один раз.
Кстати, в моем реальном коде я не передаюstd::unique_ptr<int>
, но что-то более интересное.
Наконец, я использую Xcode6-Beta4, которая использует следующую версию clang:
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix