samedi 2 mai 2020

How to move a function object to std::function? [duplicate]

I want to initialize std::function object from a function object. Here is an example of how I can do it:

#include <functional>

struct Func {
    void operator()() const
    {}
};

int main()
{
   std::function<void()> f = Func();
}

This works fine but if I add some nocopyable member to Func, the example fails to compile:

#include <functional>
#include <memory>

struct Func {
    void operator()() const
    {}

    std::unique_ptr<int> ptr;
};

int main()
{
   std::function<void()> f = Func();
}

with error message:

In file included from /opt/wandbox/gcc-9.3.0/include/c++/9.3.0/functional:59,
                 from prog.cc:1:
/opt/wandbox/gcc-9.3.0/include/c++/9.3.0/bits/std_function.h: In instantiation of 'static void std::_Function_base::_Base_manager<_Functor>::_M_clone(std::_Any_data&, const std::_Any_data&, std::false_type) [with _Functor = Func; std::false_type = std::integral_constant<bool, false>]':
/opt/wandbox/gcc-9.3.0/include/c++/9.3.0/bits/std_function.h:211:16:   required from 'static bool std::_Function_base::_Base_manager<_Functor>::_M_manager(std::_Any_data&, const std::_Any_data&, std::_Manager_operation) [with _Functor = Func]'
/opt/wandbox/gcc-9.3.0/include/c++/9.3.0/bits/std_function.h:677:19:   required from 'std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = Func; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = void; _ArgTypes = {}]'
prog.cc:13:35:   required from here
/opt/wandbox/gcc-9.3.0/include/c++/9.3.0/bits/std_function.h:176:6: error: use of deleted function 'Func::Func(const Func&)'
  176 |      new _Functor(*__source._M_access<const _Functor*>());
      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:4:8: note: 'Func::Func(const Func&)' is implicitly deleted because the default definition would be ill-formed:
    4 | struct Func {
      |        ^~~~
prog.cc:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]'
In file included from /opt/wandbox/gcc-9.3.0/include/c++/9.3.0/memory:80,
                 from prog.cc:2:
/opt/wandbox/gcc-9.3.0/include/c++/9.3.0/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;
      |       ^~~~~~~~~~

I know that std::unique_ptr is nocopyable and therefore whole Func is also nocopyable. But I don't want it to be copied to initialize std::function. I want to move temporary object Func() into std::function. How I can do it?

Aucun commentaire:

Enregistrer un commentaire