dimanche 2 août 2020

Why C++ std::function pass the functor by value instead of universal reference?

The constructor of std::function looks like this (at least in libc++):

namespace std {

template<class _Rp, class ..._ArgTypes>
function {
  // ...
  base_func<_Rp(_ArgTypes...)> __func;
public:
  template<typename _Fp>
  function(_Fp __f) : __func(std::move(__f)) {}
};

}

When std::function is initialized with a functor, there will still be a copy constructor called, for example:

struct Func {
  Func(const Func& f) {
    std::cout << "copy ctor is called" << std::endl;
  }

  Func(Func&& f) {
    std::cout << "move ctor is called" << std::endl;
  }

  void operator()() {
    // do something...
  };
};

int main(int argc, char* argv[]) {
  Func func;
  std::function<void()> f(std::move(func));
}

My question is why the constructor of std::function doesn't pass by (universal) reference, so that in the above example a copy constructor call (of class Func) could be avoided?

namespace std {

template<class _Rp, class ..._ArgTypes>
function {
  // ...
  base_func<_Rp(_ArgTypes...)> __func;
public:
  template<typename _Fp>
  function(_Fp&& __f) : __func(std::forward<_Fp>(__f)) {}
};

}

Aucun commentaire:

Enregistrer un commentaire