Мне нужно связать структуру с удаленным экземпляром copy-constructor с функцией. Я уменьшил то, что я пытаюсь достичь, следуя минимальному примеру:
struct Bar {
int i;
Bar() = default;
Bar(Bar&&) = default;
Bar(const Bar&) = delete;
Bar& operator=(const Bar&) = delete;
};
void foo(Bar b) {
std::cout << b.i << std::endl;
}
int main()
{
Bar b;
b.i = 10;
std::function<void()> a = std::bind(foo, std::move(b)); // ERROR
a();
return 0;
}
Из компилятора я получаю только плач и скрежет зубов:
test.cpp:22:27: error: no viable conversion from 'typename _Bind_helper<__is_socketlike<void (&)(Bar)>::value, void (&)(Bar), Bar>::type' (aka '_Bind<__func_type (typename decay<Bar>::type)>') to 'std::function<void ()>'
std::function<void()> a = std::bind(foo, std::move(b));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.1.0/../../../../include/c++/5.1.0/functional:2013:7: note: candidate constructor not viable: no known conversion from 'typename _Bind_helper<__is_socketlike<void (&)(Bar)>::value, void (&)(Bar),
Bar>::type' (aka '_Bind<__func_type (typename decay<Bar>::type)>') to 'nullptr_t' for 1st argument
function(nullptr_t) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.1.0/../../../../include/c++/5.1.0/functional:2024:7: note: candidate constructor not viable: no known conversion from 'typename _Bind_helper<__is_socketlike<void (&)(Bar)>::value, void (&)(Bar),
Bar>::type' (aka '_Bind<__func_type (typename decay<Bar>::type)>') to 'const std::function<void ()> &' for 1st argument
function(const function& __x);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.1.0/../../../../include/c++/5.1.0/functional:2033:7: note: candidate constructor not viable: no known conversion from 'typename _Bind_helper<__is_socketlike<void (&)(Bar)>::value, void (&)(Bar),
Bar>::type' (aka '_Bind<__func_type (typename decay<Bar>::type)>') to 'std::function<void ()> &&' for 1st argument
function(function&& __x) : _Function_base()
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.1.0/../../../../include/c++/5.1.0/functional:2058:2: note: candidate template ignored: substitution failure [with _Functor = std::_Bind<void (*(Bar))(Bar)>]: no matching function for call to object of
type 'std::_Bind<void (*(Bar))(Bar)>'
function(_Functor);
^
1 error generated.
Итак, я хотел бы спросить, есть ли какое-либо обходное решение, которое позволило бы мне привязать Bar к foo, сохраняя при этом только перемещение.
Edit:
Также рассмотрите следующий код, где заканчивается жизнь переменной b
до a
:
int main()
{
std::function<void()> a;
{
Bar b;
b.i = 10;
a = std::bind(foo, std::move(b)); // ERROR
}
a();
return 0;
}