What is the purpose of std::function? [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I was reasoning about how to write and design several functions that are supposed to deal with a specific file format which can possibly have different implementations and different versions, and each one needs a different way of decoding such information from the file .
I was browsing through the standard library as I usually do and I get a remainder that std::function exist, but the thing is I can't figure out why I can possibly be interested in using std::function, one of the first rules when programming in C and C++ is that if you don't have to refer to things you don't necessarily have to name them, and you can get unnamed data structures and unnamed/lambda functions, but functions usually have a name, and the type for a lambda is still implementation defined as far as I can remember, so what is the need for std::function ?
For example in my case I was thinking about using a map or an hash table ( but the number of functions involved is really small anyway, 2-3 max for now ) with a pair composed of tag ( which represents the version/implementation of the file format ) + functions, and I was wondering why I can't just use std::string and functions pointers as the 2 types for each pair; and I also can't really understand why we have std::function in the standard library .
I mean, when it's the case when you need a function that is unnamed and you need an object to describe its state ?

The question has been answered multiple times, with answerers from different perspectives.
C++ Functors - and their uses
Should I stop using abstract base classes/interfaces and instead use boost::function/std::function?
Callback with interfaces or function objects?
Pros & cons of a callback (std::function/std::bind) vs an interface (abstract class)
(sorted by ascending question number.)
My guess is that std::function is there to make lambda easy to use.
Basically, functors are more convenient when you need to accomplish small things. Interfaces (abstract base class, or ABC, in C++) are more suitable when things grow beyond the "small" scale.
More specifically:
When you need to implement a "one-liner" callback function, accept a std::function and implement with a lambda.
Such "one-liner" arises from:
"One-liner". Enough said.
Glue code, where you need to adapt the call signatures just a little bit to make the call pass through. Use std::bind along with std::function and lambda.
It saves you from:
Creating an interface (abstract base class, ABC) with those boilerplate,
Provide an empty body for a trivial virtual destructor (as required by some C++ compilers),
Create a class that inherits from that ABC,
Create a constructor for the "captured data" (closure) and store them in private fields,
Finally you can write the code.
With lambda, #1 goes into the std::function signature, skip #2 and #3, put #4 in a comma-separated list inside square brackets, and put #5 inside curly braces. Use auto liberally.
Anything that goes beyond "one-liner", or "one callback function", deserves an interface (ABC).
Also, if your code base is not compiled as a single piece (i.e. separations of libraries and linking), then any callback functions exposed on the library will preferably need to use an interface (ABC). This may or may not be an issue depending on your compiler and linking method.

std::function was based on the older boost::function which has good documentation, the introduction says:
Generally, any place in which a function pointer would be used to defer a call or make a callback, Boost.Function can be used instead to allow the user greater flexibility in the implementation of the target. Targets can be any 'compatible' function object (or function pointer), meaning that the arguments to the interface designated by Boost.Function can be converted to the arguments of the target function object.
The N1402 proposal to add std::tr1::function also has a section describing the motivation for the feature. It was added to the standard because thousands of people had found boost::function useful for many years.
If you still don't understand why it's useful you probably don't understand where function pointers or callbacks are useful, so look that up.

std::function<R(Args...)> type erases copy, destroy and invoke with Args... and return R, and implements move.
Start with a basic callback -- R(*)(Args...) with the Args... provided by the caller. Now a good callback has a void* you pass in to the caller, and they pass back -- now you have R(*)(void*,Args...). Next, we need to detatch and recycle the void* callback data -- so we have a void*, a R(*)(void*,Args...) and a void(*)(void*) cleanup. Next, we want value semantics -- so the caller also passes how to clone the void* -- a void*(*)(void*) clone function (value semantics are awesome, really).
And now you have a C-style version of a std::function<R(Args...)>. The std::function auto-generates the above in a constructor, and typical implementations store an interface to an abstract class that implememts the above for the passed in callable type.
So type erasure lets you take any value that supports the above type erased concepts and store them within a uniform type -- std::function<R(Args...)>.
This allows you to accept anything that matches your needs, and interact with it uniformly. You can store it in a public class, you can pass it to a dynamically loaded library, or otherwise to a chunk of code not directly dependent on the original choice of function and state.
You could use the C-style version, but it gets awkward wrapping it up.
There are variations of std::function that do away with the copy concept, and some that do away with destroy (ie, do not own), as even without that abstracting invoke is worthwhile.

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".

C++ Array of different functions

It's easy to do something like that in Python, but implementing it in C++ seems to be more challenging.
I actually have some solution to this, but I'd like to see if you can see any better solution.
Here's what I want to do.
I have a list of values of different types (string, integer, can be also instance of some class etc.). Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.
The solution I can see is that I can use std::any like this: vector<std::any> list.
I also have an array/vector of functions (or pointers to functions) with different parameter types and returned values - one function can accept string and integer and return a char and other can accept a char and return an int. Here's another problem: in C++ you can have an array/vector of functions only if they have the same parameters and returned values (as far as I know) because in your declaration of the vector you need to define the parameter types and the returned value.
The other problem is that I need to retrieve the information about the parameters and the returned value for each function. In other words, having those functions, I need to know that this function accepts 2 strings and 1 integer and returns a char for example. In Python I can use inspect.signature function to retrieve information about type annotations of a function. In C++, I don't know if there is a way to do this.
The solution I can see here is to use std::any again (although I will use another solution, I will explain why later).
The solution I can see to this problem is that I won't retrieve that information but instead the user of the class which accepts this vector of functions will simply have to specify what are the parameter types and returned value for each function. In other words, the solution I can see is that I won't be retrieving the information about parameter types programmatically.
The other problem I have is that later I need to call one of those functions with some parameters. In Python I do this like this:
arguments = [1, 'str', some_object] // here I prepare a list of arguments (they are of different types)
func(**arguments)
In C++ I can do unpacking as well, but not if the parameters are of different types.
The solution I can see here is as follows. Those functions in the vector will all accepts only argument which is vector<std::any> args which will simply contain all of the arguments. Later when I want to call the function, I will simply construct a vector with std::any values and pass it as an argument. This would also solve the previous problem of not being able to store vector of functions with different parameters.
Can you see better solutions?
You might wonder what I need all of this is for. I do some program synthesis stuff and I need to programmatically construct programs from existing functions. I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs. In order to do what I want, I need to know what are the parameters and returned values of those functions and I need to call them later.
I believe what you are looking for is std::apply. You can use std::tuple instead of std::vector to store a list of values of different types -- as long as the types are known at compile-time. Then std::apply(f, t) in C++ is basically the same as f(*t) in Python.
I have a list of values of different types (string, integer, can be also instance of some class etc.).
A type which is a union of subtypes is called a sum type or tagged union. C++ has the template std::variant for that.
Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.
Of course, so use cleverly C++ containers. You might want some std::map or std::vector of your particular instance of std::variant.
I also have an array/vector of functions
You probably want some std::vector of std::function-s and code with C++ lambda expressions
You should read a good C++ programming book
I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs.
You could get inspiration from SWIG and consider generating some C++ code in your library. So write (in Python or C++) your C++ metaprogram (generating some C++ code, like ANTLR does) which generates the user code, and your user would adapt his build automation tool for such a need (like users of GNU bison do).
You might also consider embedding Guile (or Lua) in your application.
PS. You might be interested by other programming languages like Ocaml, Go, Scheme (with Guile, and read SICP), Common Lisp (with SBCL), or Rust.

Are there any more useful use-cases of functors?

I am trying to understand cases that require using functors. Most of the answer on Stackoverflow and other websites put emphasis on being able to define different adders or multipliers regarding benefits of functors.
Can the use of functors go beyond them? What are some other uses of functors?
More often than not, functors are used with other API calls that need some kind of function object. For example, sorting vectors of user-defined objects which don't have operator() or operator< (etc.) defined.
There are some cases where a set of functors may prove useful. One such case comes when you have several algorithms which functionally do the same thing, but achieve varying levels of accuracy. This happens a lot with some numeric optimization problems: given the general form of a matrix, we might use a different technique to find the solution of a linear equation (e.g., sparse vs dense problem-matracies can employ different algorithms to invert the matrix).
In particular, you should consider functors versus lambdas. In modern versions of C++, there really isn't a need to specify a functor unless you're implementing a function/method that needs a functor (or lambda) as an argument. There are some cases to consider: Do you need a unit-test? Is the functor itself a prototype of future functionality? etc.
ADDENDUM: The key thing to consider is that the use of functor/lambda ultimately boils down to a design decision. As #t.niese noted in the comments, you could use just use functions in combination of template arguments. In addition to the previous considerations above, consider whether or not you can make a compile-time or run-time assessment of the needed functionality.
Additionally, as you make design decisions, you may want to consider "Is there a need for this function to be used outside of this specific context?" If the answer is no, that's a compelling argument to choose a lambda over a free function. With regards to functor specifically, this was an important pattern added before the addition of lambdas to the standard. Typically they're defined in a somewhat private context (frequently in the implementation files, thus after compiled into a library, obfuscated to users of the API). Now with lambdas, you can simply define them within another function or even as a function argument, instead of pre-defining them prior to need.

Is there any other advantage of lambdas besides convenience? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
The title might not be precise but I couldn't think of any brief one that would be. (Feel free to suggest one or edit my question.)
I was wondering if there is any other advantage of using lambda functions other than the fact that that one doesn't have to explicitly define (and write) the whole class definition of a functor or define a separate function to be used (possibly) just once. In other words, are lambdas introduced just for convenience or is there more to them?
Edit:
One thing to add to my question. Lambdas allow programmer to write less, do it more conveniently and therefore they are less error-prone. Which in itself is a different thing/reason than just convenience but is associated with it.
See full motivation for lamdas at A proposal to add lambda functions to the C++ standard
:
C++ Standard Library algorithms would be much more pleasant to use if C++ had support for lambdas. Lambda functions would let people use C++ Standard Library algorithms in many cases where currently it is easier to write a for loop. Many developers do not use function objects simply because of the syntactic overhead.
Lambdas are largely syntactic sugar, but not entirely. One point about lambdas is that they capture arrays by direct-initialization in subscript order [expr.prim.lambda]:
22 - [...] (For array members, the array elements are direct-initialized in increasing
subscript order.) [...]
This is surprisingly difficult to achieve otherwise; it is necessary to construct an index parameter pack using something like std::index_sequence and the semantics are not quite the same.
Another thing lambdas can do is to capture a (variadic) parameter pack; this cannot be done generically (since structure members cannot be a parameter pack expansion) except via something like std::tuple.
Basically: They exist for your convenience.
In addition to Maxim's answer, according to the MSDN article about Lambda Expressions in C++:
When you write code, you probably use function pointers and function
objects to solve problems and perform calculations, especially when
you use STL algorithms. Function pointers and function objects have
advantages and disadvantages—for example, function pointers have
minimal syntactic overhead but do not retain state within a scope, and
function objects can maintain state but require the syntactic overhead
of a class definition.
A lambda combines the benefits of function
pointers and function objects and avoids their disadvantages. Like a
function objects, a lambda is flexible and can maintain state, but
unlike a function object, its compact syntax doesn't require a class
definition. By using lambdas, you can write code that's less
cumbersome and less prone to errors than the code for an equivalent
function object.
The one advantage to captureless lambdas over the corresponding function object is that they are convertible to function pointers.
Using STL algorithms becomes more convenient.
If you want to write
reusable code in your function but might not make sense to put it in
a free function, then lambdas come to the rescue.
For eg.
void foo()
{
auto validate = [] (const std::string& str) -> bool { // do some validation. };
/// ... code.
if (!validate("some info"))
{
// throw error;
}
////
validate("some other info");
}

Advantages of 'pointer to a function' when using design patterns

In C++ we can make pointers to functions. So that we can pass a 'pointer to a function' as an argument to another function. When we consider about design patterns, are there any specific design patterns which specially take the advantage of using 'pointer to a function'?
Any design pattern that makes use of callbacks; such as visitor, strategy, and observer. Note that in C++, functors are also available to you and are generally preferred by the STL.
Most anything you can achieve with a pointer to a function, you can achieve with a functor with better optimization, or with virtual methods for better OO design. However, a pointer to a function is a requirement for narrow use cases where C code and C++ code are interfacing with each other. An OO design pattern can still allow C code to participate in the pattern. And, certain C interfaces only accept function pointers, so C++ code that use those APIs have to pass one in.
A function pointer is generally used as a means to call some code that is registered in some kind of subscription/publish model (event notification). For example, it could be used for the handle() method in the state pattern.
But, it can also be used as a simple hook to get code to run within a particular framework. For example, pthread_create takes a function pointer that is to be called after a thread is launched.
I generally see this done when a certain part of a function needs to be customized for certain cases. Allowing for the same function to take on multiple uses, this is demonstrated in the for_each function of C++, which goes through an iterable and applies a function to it. It really just allows for more reusable code.
On a related note, the C++ standard library uses a similar setup for it's container classes.
For example:
template < class T, class Container = deque<T> > class stack;
is the decleration for the stack class. As you can see, it takes in a configurable parameter for what it's underlying data structure is, this is similar to how a function pointer could be used.
EDIT: or the mentioned callbacks from other posters.