When should you ever use functions over functors in C++? - c++

Functors are apparently more efficient since the compiler is more easily able to inline them, and they work much better with parametrization. When should you ever use a plain old function over a functor?

Functions support distributed overriding. Functors do not. You must define all of the overloads of a Functor within itself; you can add new overloads of a function anywhere.
Functions support ADL (argument dependent lookup), permitting overloading in the argument-type associated namespace. Functors do not.
Function pointers are (kind of) a type-erased stateless functor that is a POD, as evidenced by how stateless lambdas convert into it. Such features (POD, stateless, type erasure) are useful.

Related

What is the advantage of using boost::bind?

The definition and application of boost::bind are clearly outlined in the boost website, yet I hardly could find what is the benefit of using it over using a normal function call? Or to put it simply in which scenarios it might come in handy?
Sometimes you have a set of arguments that you are going to pass to the function, but you wish to call the function later without needing to pass the arguments that are already known. One reason to need this may be because the call may need to conform to an interface that doesn't allow those arguments. This is typical in the (functor style) "callback" idiom.
That situation can be solved by defining a class that stores the arguments as members, and defines function call operator overload that delegates to the original function and passes the arguments stored as members.
boost::bind is a structured way to represent such "argument binding" without needing to define the class yourself. The standard library used to have std::bind1st and std::bind2nd which were more limited, less generic forms of bind.
boost::bind is rarely needed anymore since it was introduced to the standard library as std::bind in C++11, and furthermore lambdas were introduced in C++11 and improved in C++14 and they have largely obsoleted bind.
bind provides a way to take a function or a function object with a certain arity and transform it to another function with lesser arity by precisely binding one or more arguments. And you can do it in place.
bind and functions don't have a good comparison.
bind is more comparable to simple lambdas that call a function and fix certain parameters in their implementation.
The big difference between boost::bind and a modern lambda is that the bind object has a certain degree of instrospection associated with it that the lambda doesn't have.
For example you could in principle recover the original function and reconstruct what is the argument bound.
In a lambda everything is private, even the simplest implementation.
In other words, the result of boost::bind is an "expression" and the type has well defined pattern (e.g. boost::bind_t<...> or something, and that can be matched in a template function argument).
Lambdas instead are each their own unknowable sui generis type.
Admittedly, few people maybe interested in the difference, but it is there and I played with it once or twice to implement a symbolic system (for derivatives).
I can't say the same about std::bind because the object returned is unspecified by the standard and it could be more difficult to reconstruct the full bind "expression".

When to not use lambdas over normal functions?

I am aware how a lambda works, I use lambdas pretty much everywhere in my code, is there any scenario where I should prefer using normal functions instead of lambdas
When not to use lambdas:
When the function is declared in a header and implemented in a .cpp files. Can't do this with lambda.
When the function is a template, and you want to be able to manually specify template arguments. Doing this with lambas requires an ugly syntax: foo.operator()<...>(...).
When to use lambdas:
When the function is overloaded/templated, and you want to conveniently pass it as an argument to a different function.
You want to avoid ADL.
Other than that, preferring regular functions over lambdas is just a convention.
If you want to go against this convention, you should be prepared to explain your reasoning.
When to not use lambdas over normal functions?
Using a normal function is often preferable when the function can be re-used in multiple contexts.

Why std::function::argument_type has been deprecated?

I've seen on cppreference that std::function::argument_type was deprecated in C++17. What is the reason behind it? And what ISO WG21 paper was proposing that?
The relevant papers are P0005R4 (which is the paper that was voted into the draft standard) and P0090R0 (which is referenced by P0005R4).
Quotes from P0090R0:
Q2. What's wrong with result_type, etc.?
A2. These C++98/03/TR1-era typedefs predated decltype and perfect
forwarding. Previously, generic code had to request information from
function objects before adapting them. Now, manually communicating
that information is unnecessary. decltype supersedes result_type,
because the compiler can simply report what the result of calling a
function object with specific arguments will be. And perfect
forwarding supersedes the argument_type family, since adaptors can
simply take/store/forward arbitrary arguments.
In fact, these typedefs are worse than useless. They're
counterproductive, because many callable objects lack them. Function
pointers and pointers to members have always lacked them. ptr_fun(),
which wrapped function pointers with these typedefs, was recently
removed (see [1] again). Most importantly, lambdas have always lacked
these typedefs, and they are the most important function objects of
all. Generic lambdas are even more incompatible.
What this means is that if a user attempts to write generic code by
using the result_type family of typedefs, their code won't be generic
- it'll fail to handle lambdas, generic lambdas, function pointers, etc.
These typedefs should be removed because they've become actively
harmful to modern code.
The reason those typedefs exist are so things like not1, bind1st and friends, could query the callables passed to them and retrieve the type of the result of invoking the callable, its argument types etc.
To make their use palatable, a lot of support machinery, like unary_function, ptr_fun, mem_fun etc. were also defined. Notice how all of these are limited to adapting callables taking one or two arguments only, so they're rather limited in that sense.
Now that we have decltype that can be used to deduce a callable's return type, variadic templates and perfect forwarding to forward arbitrary number of arguments to functions, etc. the pre-C++11 mechanisms are way too cumbersome to use.
Stephan T Lavavej first proposed getting rid of these in C++17 in p0090r0. Relevant excerpts from the paper:
Q1. What are you proposing?
* Removing every mention of result_type, argument_type, first_argument_type, and second_argument_type ...
* Removing the negators not1() and not2(), which were powered by these
typedefs.
Q2. What's wrong with result_type, etc.?
A2. These C++98/03/TR1-era typedefs predated decltype and perfect forwarding. Previously, generic code had to request information from function objects before adapting them. Now, manually communicating that information is unnecessary. decltype supersedes result_type, because the compiler can simply report what the result of calling a function object with specific arguments will be. And perfect forwarding supersedes the argument_type family, since adaptors can simply take/store/forward arbitrary arguments.
If you search the paper for [func.wrap.func], it talks specifically about removing the std::function typedefs you're asking about.

Why are C++11 string new functions (stod, stof) not member functions of the string class?

Why are those C++11 new functions of header <string> (stod, stof, stoull) not member functions of the string class ?
Isn't more C++ compliant to write mystring.stod(...) rather than stod(mystring,...)?
It is a surprise to many, but C++ is not an Object-Oriented language (unlike Java or C#).
C++ is a multi-paradigm language, and therefore tries to use the best tool for the job whenever possible. In this instance, a free-function is the right tool.
Guideline: Prefer non-member non-friend functions to member functions (from Efficient C++, Item 23)
Reason: a member function or friend function has access to the class internals whereas a non-member non-friend function does not; therefore using a non-member non-friend function increases encapsulation.
Exception: when a member function or friend function provides a significant advantage (such as performance), then it is worth considering despite the extra coupling. For example even though std::find works really well, associative containers such as std::set provide a member-function std::set::find which works in O(log N) instead of O(N).
The fundamental reason is that they don't belong there. They
don't really have anything to do with strings. Stop and think
about it. User defined types should follow the same rules as
built-in types, so every time you defined a new user type,
you'd have to add a function to std::string. This would
actually be possible in C++: if std::string had a member
function template to, without a generic implementation, you
could add a specialization for each type, and call
str.to<double>() or str.to<MyType>(). But is this really
what you want. It doesn't seem like a clean solution to me,
having everyone writing a new class having to add
a specialization to std::string. Putting these sort of things
in the string class bastardizes it, and is really the opposite
of what OO tries to achieve.
If you were to insist on pure OO, they would have to be
members of double, int, etc. (A constructor, really. This
is what Python does, for example.) C++ doesn't insist on pure
OO, and doesn't allow basic types like double and int to
have members or special constructors. So free functions are
both an acceptable solution, and the only clean solution
possible in the context of the language.
FWIW: conversions to/from textual representation is always
a delicate problem: if I do it in the target type, then I've
introduced a dependency on the various sources and sinks of text
in the target type---and these can vary in time. If I do it in
the source or sink type, I make them dependent on the the type
being converted, which is even worse. The C++ solution is to
define a protocol (in std::streambuf), where the user writes
a new free function (operator<< and operator>>) to handle
the conversions, and counts on operator overload resolution to
find the correct function. The advantage of the free function
solution is that the conversions are part of neither the data
type (which thus doesn't have to know of sources and sinks) nor
the source or sink type (which thus doesn't have to know about
user defined data types). It seems like the best solution to
me. And functions like stod are just convenience functions,
which make one particularly frequent use easier to write.
Actually they are some utility functions and they don't need to be inside the main class. Similar utility functions such as atoi, atof are defined (but for char*) inside stdlib.h and they too are standalone functions.

Function pointers and functors

Are function pointers functors ? Is there a virtual functor in use that helps sibling functors compile silently ?
At least as the term is normally used in C++ (Warning: it's used entirely differently relative to other languages such as Haskell), a functor is a class (or an instance of a class) that overloads operator() so it can be invoked like a function.
Since they use the same syntax, a template can be written to accept either a pointer to a function or an instance of a functor interchangeably. Not all algorithms will do so however -- some expect (for example) that you supply something with typedefs for things like argument_type and result_type. The standard library provides a couple of classes (unary_function and binary_function) to use as base classes for your functors to supply these. You can supply them on your own if you prefer -- these base classes are purely for convenience (and some people don't find them particularly convenient).
A function pointer is the address of a real function. A functor is a class for which the operator() has been overloaded; instances of these classes can be passed around and called with the same syntax as a function. So no, function pointers are not functors.
I don't know what "virtual functors" or "sibling functors" are, so I can't answer your second question.