Why a template functor is passed as a value rather than forwarding a link

In the discussion, we are here. I played with transmitting functors. C ++ STL passes functors as values ​​(see std::for_each , std::find_if , std::transform )

So my ad will be like that.

 template<typename F> void call_me(F f) { f(); } 

Now calling call_me(ftor{}) can probably call the ftor copy constructor (most likely it will be copied, so it is not). But ftor f{}; call_me(f); ftor f{}; call_me(f); will result in copying. If ftor has big data, this can be a problem.

We will improve it by passing it as a const reference ( void call_me(const F& f) ) to get rid of an unnecessary copy. This is normal if ftor::operator() is const . If this is not the case, calling call_me will result in a compilation error (losing const qualifiers).

So, why bother with a constant link, use only the link ( void call_me(F& f) ). This is normal, but that would not work for the first case call_me(ftor{}) , since an invalid r-value (not const const) l-value is invalid.

Declaring f as forwarding links ( void call_me(F&& f) ) seems to work in all cases. I believe this works by dropping links.

So, why aren't template functors passed as forwarding links to functions from STL?

+8
c ++ c ++ 11 templates
source share
1 answer

why are template functors not passed as r-value references in functions from STL?

First of all, they will redirect links, not links to rvalue.

However, like many β€œwhy” questions about the design of the language as a whole, the answer may be simple: because no one has proposed this change (see how to send an offer ). I suspect that a lot of function objects passed to standard library algorithms, either lambdas or stateless, or are extremely cheaply copied. Moreover, if you have such an expensive object, you can always turn it into an inexpensive copy for the purpose of the algorithm:

 call_me(std::ref(huge_object)); 

Finally, some of these algorithms rely on passing objects of these functions to other helpers. If the algorithm simply assumes that the function object is β€œfree” to copy, this simplifies coding. If we introduce the possibility of rvalues ​​here, this will add another level of questions that need to be addressed - are we just going to the link? What about function objects with ref-qual operator() ?

Some combination of the above probably explains why, for example, this is still:

 template <class InputIt, class UnaryPredicate> InputIt find_if(InputIt, InputIt, UnaryPredicate ); 

but not

 template <class InputIt, class UnaryPredicate> InputIt find_if(InputIt, InputIt, UnaryPredicate&& ); 
+9
source share

All Articles