There are a lot of examples on the web of using STL to pass in functions or function objects as parameters, for example in std::count .
How do I write my own functions that take such arguments?
As a simple example, say my class is:
struct Foo{
int val=0;
int methodinc()const{return val+1};
}
I would like to define a function funcall like:
int funcall (foo arg, function f)
{return f(arg); }
where the declaration “function” is what I am not sure of, among other things. The term “funcall” comes from Lisp, where (funcall f a b c) just applies f to the arguments a b c.
Then something like this should work:
Foo ff;
funcall(ff,Foo::methodinc); // should return 1
funcall(ff, [](Foo x) {return x.val+1;}) // should return 1
What are simple ways to accomplish this?
I am writing these as debugging helpers, the “funcall” would be used as part of the implementation of my own like my own data structure’s analogs of count, remove-if, transform and other like STL functions that take function arguments. But I do not want to write complicated template expressions to define my code.
The initial answers to this question suggest that the whole notion of declaring and using function arguments is a bit obscure, at least to me. Perhaps before addressing funcall, an even easier task might be just to pass a functional argument to another function, not use it. For example, in C++, to count a vector v I have to write
std::count(v.begin, v.end(), [](int j){return j>3})
How can one write a count that always counts the whole vector, so that:
mycount(v,[](int j){return j>3})
is the same as above? And could this "mycount" work for member function pointers instead of lambdas?
This question is basically the same as the "funcall" question but without the requirement actually to call the function object that is passed.
Typically a function template suits this sort of need for flexibility best:
template <typename F, typename T>
auto funcall(T && t, F f) -> decltype(f(std::forward<T>(t))
{
return f(std::forward<T>(t));
}
Instead of the trailing return type and decltype you can also use the result_of trait:
template <typename F, typename T>
typename std::result_of<F(T&&)>::type funcall(T && t, F f)
{
return f(std::forward<T>(t));
}
Or, in C++14, you can just say decltype(auto) funcall(T && t, F f) with no trailing return type, and it'll be deduced automatically.
The main reason for making F a deduced template argument rather than a fixed type (such as std::function<R(T)> is to allow you to call funcall directly with lambdas and bind/mem_fn expressions, which have unknowable types. Passing those directly allows efficient inlining opportunities, whereas creating of an std::function object is rather expensive by comparison.
C++ is an extraordinarily powerful and complex language. In it you can do anything you can do in Lisp, including implementing Lisp yourself. The problem is that to get there you will have to learn rather a lot about the language and what it can do. Using functions as objects is unfortunately one of the most complicated parts of C++.
There are multiple ways to solve your problem. The #Kerrek answer is an excellent one, but clearly beyond what you're ready for. The code provided in your edit is for a lambda, which will not necessarily make things simpler.
At its heart, function objects in C++ are just pointers. They look like this.
typedef int (*func)(int a, char b);
int f(int aa, char bb) {
return aa + bb;
}
int main(void) {
func fv = f;
int ret = fv(10, ' ');
printf ("ret=%d", ret);
return 0;
}
Here func is a type representing a function call, f is the actual function and fv is a functional call variable.
From this structure all else is built. With templates the compiler does the type matching and with lambdas you avoid having to think up nmes. Underneath it all, C/C++ functions are just pointers.
So the answer is that you can write your own functions that take functions as arguments when you know that those arguments are simply pointers to functions of a suitable type, declared as shown above.
Related
There is a common abstraction for both containers and functions. I learned it in Haskell, and I'm trying to implement it in C++.
Most C++ programmers are familiar with std::transform, roughly speaking given a function from type A to B, you can convert a container of type A to a container of type B.
You can transform functions in a similar way, given a function foo from A to B, you can convert a function bar taking Z to A to a function foo . bar taking Z to B. The implementation is simple, it's just composition.
I wanted to define a function fmap, on containers and functions, to reflect this abstraction for generic programming.
The container was easy (I know this isn't fully general)
template <typename A, typename Func>
auto fmap(Func f, vector<A> in) {
vector<decltype(f(in[0]))> out_terms{};
for(auto vec : in)
out_terms.push_back(f(vec));
return out_terms;
}
However, the analogous function for functions makes me much more nervous.
template <typename FuncT, typename Func>
auto fmap(FuncT f, Func in) {
return [f, in](auto x){
return f(in(x));
};
}
Although the template won't specialize for anything except callable things, I'm worried this will confuse overload resolution. I would like to introduce type constraints on the template parameters to restrict their resolution to function types to keep the name space clean. And I was going to ask how to do that.
This abstraction is extremely general, there are corresponding fmaps for pointers to values, which I suspect might conflict as well.
So I think my question is, can I have two different template implementations with the same template level signature? I'm almost certain the answer is no but maybe something similar can be faked. And if not, what tools are available today to distinguish between the overloads? Especially for function types.
This seems, to me, to be a textbook case for concepts, though I'm not sure.
Edit: Boost would be acceptable to use, and SFINAE in particular. I'm trying to find a solution that would be familiar to most programmers, and as convenient, and canonical as possible. I could rename fmap to compose, but then the programmer would have to know to pass compose to a template function accepting fmap. That would be unfortunate, because fmap is semantically unique.
Edit 2: A trivial example of how this is used.
template <typename T>
auto double_everything(T in){
auto doublef = [](auto x){return 2*x;};
return fmap(doublef, in);
}
It generalizes maps over containers to maps over "container like" things. So double_everything(vector<int> {1, 2, 3}) returns a vector with its elements doubled. But double_everything([](int x){ return x + 1; }) returns a function whose outputs are twice the outputs of the increment function. Which is like doubling a kind of list. The abstraction has some nice properties, I'm not just making it up. At any rate, renaming the function fmap to compose doesn't answer the question.
Edit 3:
fmap for a template C takes functions from A to B to functions from C<A> to C<B> and satisfies fmap( compose(f, g) , c ) = fmap( f, fmap( g, c )). This is a nice structure preserving property.
Functions which do this for ranges already exist by different names. But ranges aren't the only templates on types. Here is fmap for std::optional:
template<typename T, typename Func>
auto fmap(Func f, optional<T> o) -> optional<f(*o)>{
if(o)
return f(*o);
else
{};
}
This implementation doesn't involve any range concepts at all, like thefmap for functions presented earlier. But it satisfies the semantic requirements for fmap.
I'm trying to define fmap for different overloads in the same way I would define a new operator * for a custom matrix type. So I would happily define fmap in terms of boost::transform_iterator. Then these algorithms would work with a function generic in terms of fmap.
Here is an example of such a function:
template <
template<typename, typename> class Cont,
typename Fmappable,
typename Alloc,
typename Func>
auto map_one_deep(Func f, Cont<Fmappable, Alloc> c){
auto g = [f](Fmappable x){ return fmap(f, x); };
return fmap(g, c);
}
now if we write
auto lists = vector<vector<int> > { {1, 2, 3}, {4, 5, 6} };
auto lists_squared = map_one_deep( [](int x){return x*x;} , lists);
lists_squared printed gives
1 4 9
16 25 36
If we instead had a vector of optionals, the optionals would be squared provided they contained elements.
I'm trying to understand how one should work with higher order functions in c++.
You can fake it with SFINAE, but you shouldn't. It's a matter of style and idiom.
Haskell is all about type classes, with a programmer expecting to have to spangle each type with all the clubs it belongs to. C++, in contrast, wants to be more implicit in specifying a type's capabilities. You've shown "vector" and "arbitrary callable" there, but why just vector? Why not an arbitrary container type? And this arbitrary container type I just wrote has an operator(), because reasons. So which one should it choose?
Bottom line, while you can use SFINAE tricks to resolve technical ambiguities, you shouldn't use them to resolve essential ambiguities. Just use two different names.
Here's the simplest compromise I found
template <typename FuncT, typename O, typename T>
auto fmap(FuncT f, function<O(T)> in){
return [f, in](T x){
return f(in(x));
};
}
Unfortunately this requires that function<Output(Input)> decorate the call site, and it litters indirections. I'm pretty sure this is the best one can do if constraining fmap is required.
Edit: You can do better. The link gives a way to restrict to callables, that also in-lines.
The function could be written like this:
template <typename FuncT, typename T>
auto fmap(FuncT f, tagged_lambda<T> in){
return tag_lambda([f, in](T x){
return f(in(x));
});
}
You could choose the version you want at the call site, by calling
fmap(g, tag_lambda({}(int x){return x + 1;}) );
or
fmap(g, function<int(int)>({}(int x){return x + 1;}) );
Given how templates work, I'm pretty sure tagging the function is required.
Here is a blog post which also talks about the issue, and discusses other options.
http://yapb-soc.blogspot.com/2012/10/fmap-in-c.html.
So I understand using var in C# makes sense because you have anonymous types that are compiler derived. C++ doesn't seem to have this feature (unless I'm wrong), so what is the point of having an auto keyword?
(It is kinda cool that unlike C#, auto does work for member/global variables, which is cool I guess, but doesn't seem enough to justify its existence).
auto has a lot of uses when it comes down to both generic programming and to save the programmer some typing.
For example, consider this. Would you rather type out:
std::unique_ptr<name::long_type::goes_here> g =
std::make_unique<name::long_type::goes_here>(1,2,3,4)
or:
auto g = std::make_unique<name::long_type::goes_here>(1,2,3,4)
Yes, they're both long but we know the return type and specifying it again is a bit cumbersome to type. This also goes for iterators:
for(auto i = vec.begin(); ...)
vs:
for(std::vector<type>::iterator i = vev.begin(); ...)
Its use in generic programming is also to figure out the return type of a function or if you're doing some generic algorithms where you don't know the type.
For example, consider a very basic example.
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
This allows the compiler to figure out the type of the add operation rather than us trying to figure it out ourselves. Note that in C++14 you can omit the trailing return type. Its uses in generic programming don't stop there either. If we wanted to work with any type of container as a wrapper function for algorithms we could use auto to help us with it. For example:
template<class Cont>
void my_sort(Cont&& cont) {
using std::begin;
auto first = begin(std::forward<Cont>(cont));
// work with the iterators here
}
In the future (C++14), auto can be used to make polymorphic lambdas as well such as:
[](auto a) { return a + 4; }
Which can be useful as well.
There are a number of uses for auto in C++
Anonymous function objects, aka closures, aka lambda instances. auto is the only way to store them. Types can also be generated derived off those types, and types on their backs, ad infinitum.
C++ can have quite complex types, such as the type of a non mutating iterator into an unordered map that uses a custom allocator and hashing function. typedef can mitigate this, but the type of a m.begin() having a particular name is not that informative: foo_iterator it = is as meaningful as auto foo_iterator =, and the auto one does not require boilerplate elsewhere.
Return type deduction uses the auto keyword, which is required to do some template functions work without huge amounts of traits boilerplate. Eliminating boilerplate is a common theme: C++s robust type system means that types can carry lots of information, and encoding it at every use can be counterproductive.
In some ducktype template code, the work to deduce the type of a variable is roughly the same as the work to code the variables value, and nearly identical in structure, some times literally: decltype(long expression) x = long expression;. auto eliminates that duplication.
Finally in C++1y, type deduction lambdas use auto to say that an argument is a deduced one. Sort of a light weight template. Talk to extend this to non lambdas is also in skunkworks.
HEre's a real life example where I could not, not use auto
I was trying to do a switch type statement in C++ where the return type is implementation specific and could not be declared easily. So using an 'auto' is probably the right way to resolve the type look up for the map declaration.
auto foo = boost::bind(&VegaFactory::load_commodity_one_leg,this,conn,_1);
std::map<std::string,decltype(foo)> methods;
methods.insert(std::make_pair("FOO",commodityOneLeg));
auto f = methods.find(bar);
// Call f here
C++ does have "anonymous" types - types you cannot refer to by name because the name is not available to you. This was the case even before C++11 and lambdas. Consider the following code:
class foo {
class bar {
public:
void baz() { }
};
public:
static bar func() { return bar(); }
};
foo::func().baz(); // OK, only the name "bar" is private
??? a = foo::func(); // Umm...
auto b = foo::func(); b.baz(); // Hooray!
Even if not actually declared in a private scope, it is often useful for a library to leave some types unspecified in its API - especially when heavily utilizing expression templates or other template metaprogramming where the type names can be arbitrarily long with all the nested template arguments. Even the standard itself does this - for instance, the result type of std::bind is not defined by the specification.
syntactic sugar
I rather say
auto i = mapping.begin();
over
std::map<int, int>::iterator i = mapping.begin();
It is well worth reading Herb Sutter's article Almost Always Auto for some great examples of why it's worth using auto over explicit types. The main advantages are the reduction in typing, and gives additional safety if the underlying types change. One of my favourite examples though is about how it reduces duplication. If you allocate on the stack then you'd use:
MyClass c(param);
However, if you want to create on the heap you need:
MyClass* c=new MyClass(param);
So you've had to duplicate the MyClass, but the RHS already forces the variable to be a MyClass pointer, so you can just use this instead:
auto c=new MyClass(param);
If you want to declare it as a unique_ptr then previously you would need:
unique_ptr<MyClass> c=make_unique<MyClass>(param);
which can be abbreviated to:
auto c=make_unique<MyClass>(param);
In C++, auto keyword provides a way of type deduction mechanism. For example,
auto i = expressions;
auto keyword tells the compiler to determine the type of variable i from the expression on the right side of the assignment operator.
Therefore if the value of expressions is double, then variable i will be double. Or, if the value of expressions is bool, then variable i will be bool.
so, let's learn type inference first which is basically refers to automatic deduction of the data type of an expression in a programming language.
before C++ 11 all the variables in c++ have to explicitly declare but after the release of c++ 11, the compiler itself deduces the type of the variable at runtime.
we can use it for variables and even in the case of function return types.
but, it's suggested to avoid using auto in function return type.
I am playing around with the c++11 functional features. One thing I find odd is that the type of a lambda function is actually NOT a function<> type. What's more, lambda's do not seem to play really well with the type-inferencing mechanism.
Attached is a small example in which I tested flipping the two arguments of a function for adding two integers. (The compiler I used was gcc 4.6.2 under MinGW.) In the example, the type for addInt_f has been explicitly defined using function<> while addInt_l is a lambda whose type is type-inferenced with auto.
When I compiled the code, the flip function can accept the explicitly type-defined version of addInt but not the lambda version, giving an error saying that,
testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
The next few lines show that the lambda version (as well as a 'raw' version) can be accepted if it's explicitly cast to the appropriate function<> type.
So my questions are:
Why is it that a lambda function does not have a function<> type in the first place? In the small example, why does not addInt_l have function<int (int,int)> as the type instead of having a different, lambda type? From the perspective of functional programming, what's the difference between a function/functional object and a lambda?
If there is a fundamental reason that these two have to be different. I heard that lambda's can be converted to function<> but they are different. Is this a design issue/defect of C++11, an implementation issue or is there a benefit in distinguishing the two as the way it is? It seems that the type-signature of addInt_l alone has provided enough information about the parameter and return types of the function.
Is there a way to write the lambda so that the above mentioned explicit type-casting can be avoided?
Thanks in advance.
//-- testCppBind.cpp --
#include <functional>
using namespace std;
using namespace std::placeholders;
template <typename T1,typename T2, typename T3>
function<T3 (T2, T1)> flip(function<T3 (T1, T2)> f) { return bind(f,_2,_1);}
function<int (int,int)> addInt_f = [](int a,int b) -> int { return a + b;};
auto addInt_l = [](int a,int b) -> int { return a + b;};
int addInt0(int a, int b) { return a+b;}
int main() {
auto ff = flip(addInt_f); //ok
auto ff1 = flip(addInt_l); //not ok
auto ff2 = flip((function<int (int,int)>)addInt_l); //ok
auto ff3 = flip((function<int (int,int)>)addInt0); //ok
return 0;
}
std::function is a tool useful to store any kind of callable object regardless of its type. In order to do this it needs to employ some type erasure technique, and that involves some overhead.
Any callable can be implicitly converted to a std::function, and that's why it usually works seamlessly.
I'll repeat to make sure it becomes clear: std::function is not something just for lambdas or function pointers: it's for any kind of callable. That includes things like struct some_callable { void operator()() {} };, for example. That is a simple one, but it could be something like this instead:
struct some_polymorphic_callable {
template <typename T>
void operator()(T);
};
A lambda is just yet another callable object, similar to instances of the some_callable object above. It can be stored in a std::function because it's callable, but it doesn't have the type erasure overhead of std::function.
And the committee plans to make lambdas polymorphic in the future, i.e., lambdas that look like some_polymorphic_callable above. Which std::function type would such a lambda be?
Now... Template parameter deduction, or implicit conversions. Pick one. That's a rule of C++ templates.
To pass a lambda as a std::function argument, it needs to be implicitly converted. Taking a std::function argument means that you're choosing implicit conversions over type deduction. But your function template needs the signature to be deduced or provided explicitly.
The solution? Don't restrict your callers to std::function. Accept any kind of callable.
template <typename Fun>
auto flip(Fun&& f) -> decltype(std::bind(std::forward<Fun>(f),_2,_1))
{ return std::bind(std::forward<Fun>(f),_2,_1); }
You may now be thinking why do we need std::function then. std::function provides type erasure for callables with a known signature. That essentially makes it useful to store type-erased callables and to write virtual interfaces.
Because function<> employs type erasure. This allows several different function-like types to be stored in a function<>, but incurs a small runtime penalty. Type erasure hides the actual type (your specific lambda) behind a virtual function interface.
There is a benefit to this: one of the C++ design "axioms" is to never add overhead unless it is really needed. Using this setup, you do not have any overhead when using type inference (use auto or pass as a template parameter), but you still have all the flexibility to interface with non-template code through function<>. Also note that function<> is not a language construct, but a component of the standard library that can be implemented using simple language features.
No, but you can write the function to just take the type of the function (language construct) instead of the specifics of the function<> (library construct). Of course, that makes it a lot harder to actually write down the return type, since it does not directly give you the parameter types. However, using some meta-programming a la Boost.FunctionTypes you can deduce these from the function you pass in. There are some cases where this is not possible though, for example with functors that have a templated operator().
This question already has answers here:
Should I use std::function or a function pointer in C++?
(6 answers)
Closed 5 years ago.
Whats the difference between std::function<> and a standard function pointer?
that is:
typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);
Are they effectively the same thing?
A function pointer is the address of an actual function defined in C++. An std::function is a wrapper that can hold any type of callable object (objects that can be used like functions).
struct FooFunctor
{
void operator()(int i) {
std::cout << i;
}
};
// Since `FooFunctor` defines `operator()`, it can be used as a function
FooFunctor func;
std::function<void (int)> f(func);
Here, std::function allows you to abstract away exactly what kind of callable object it is you are dealing with — you don't know it's FooFunctor, you just know that it returns void and has one int parameter.
A real-world example where this abstraction is useful is when you are using C++ together with another scripting language. You might want to design an interface that can deal with both functions defined in C++, as well as functions defined in the scripting language, in a generic way.
Edit: Binding
Alongside std::function, you will also find std::bind. These two are very powerful tools when used together.
void func(int a, int b) {
// Do something important
}
// Consider the case when you want one of the parameters of `func` to be fixed
// You can used `std::bind` to set a fixed value for a parameter; `bind` will
// return a function-like object that you can place inside of `std::function`.
std::function<void (int)> f = std::bind(func, _1, 5);
In that example, the function object returned by bind takes the first parameter, _1, and passes it to func as the a parameter, and sets b to be the constant 5.
They are not the same at all. std::function is a complex, heavy, stateful, near-magic type that can hold any sort of callable entity, while a function pointer is really just a simple pointer. If you can get away with it, you should prefer either naked function pointers or auto-bind/auto-lambda types. Only use std::function if you really need a systematic way of organizing a heterogeneous collection of callable entities, such as functions, functors, capturing lambdas and bind expressions.
Update: A bit of explanation about auto types: Compare the following two functions:
void do_something_1(std::function<void(int)> f, int a) { f(a); }
template <typename F, typename A> void do_something_2(F f, A a) { f(a); }
Now imagine invoking them with a lambda or a bind expression:
do_something_X([foo, &bar](int n){ bar += n*foo; }, 12);
do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13);
The second version with the template is more efficient, because in both cases, the argument F is deduced to the actual, unknowable type of the expression. The first version, with std::function, isn't a template and may look simpler and more deliberate, but it always forces the construction of the std::function object, and quite possibly carries multiple type erasure and virtual dispatch costs.
A std::function has state. It can hold additional parameters "bound" into it.
These parameters can range from things like other classes, other functions, or even this pointers for member function calls.
The replacement function pointer is not typedef int (*fn)(int);
It is typedef int (*fn)(void*,int);, with the void* reperensting the state that would be hidden in the std::function.
No.
One is a function pointer; the other is an object that serves as a wrapper around a function pointer.
They pretty much represent the same thing, but std::function is far more powerful, allowing you to do make bindings and whatnot.
I am coding in C++ and have a few questions regarding the ellipsis:
Is it possible to pass in class or class pointer into the ellipsis?
Basically what I want to do is to pass in variable number of arguments in the type of char* and class. I am using ellipsis currently and trying to figure out how to pass in the class. If ellipsis isn't applicable over here, what are the options available?
I want to let the user to directly call the function using func( params 1, params2, ...) without explicitly assigning the params into a vector or array first before passing the vector or array as argument to the function.
You should consider that using variadic functions (C-style) is a dangerous flaw.
If the objects passed to the function mismatch the type awaited, or if you don't put the exact number of parameters awaited, then you basically have a violent crash at runtime.
In Bjarne Stroustrup C++ In Depth Series - C++ Coding Standards - 101 Rules, Guidelines, And Best Practices by Herb Sutter and Andrei Alexandrescu, chapter 98: Don't use varargs (ellipsis)
I deeply subscribe to #tenfour's proposal:
use an std::vector that contains all your parameters.
You can pass whatever you want to variadic functions, but this won't help you in writing convenient functions as you are losing the type information for the arguments.
Depending on what you want to achieve there are better alternatives:
chaining operators like << or ():
helper() << a << b << c;
helper(a)(b)(c);
using (pseudo-)variadic templates:
template<class T0> void func(T0 t0) { ... }
template<class T0, class T1> void func(T0 t0, T1 t1) { ... }
// ...
// or if you can use C++0x features:
template<class... Args> void func(Args... args) { ... }
... more?
You can pass a class pointer with varargs, yes. But the function receiving the pointer needs to know what to do with it. It will have to cast it to something usable. This is why printf() makes you specify the argument type in the format specifier.
One alternative is to pass a list to the function, like std::vector.
[edit] You might be want to do something to make the syntax shorter, so you can pass in your arguments like:
foo(blah, StartAList(a)(b)(c)(d));
or stream-ish:
foo(blah) >> a >> b >> c >> d;
or by overloading:
void foo(T a) { ... }
void foo(T a, T b) { ... }
void foo(T a, T b, T c) { ... }
Using C++0x variadic templates, you can pack all your arguments into a tuple and use the code I posted in the thread below to unpack them into a function call (static function or object function).
How do I expand a tuple into variadic template function's arguments?
True typesafe variable argument functions are possible with the newly introduced feature variable template arguments in C++0x
You can also get by using boost::any
If class instance (or pointer) is used always, it is better to use fixed parameter, which is passed before variable parameters list, like format in printf. Regarding ... parameters, they may have any type (including class instance or pointer), and their amount and types depend on some convention between a caller and called function. For example, for printf, such convention is defined by format string. You need to define such "communication protocol", which allows to use variable arguments list. Of course, this is not safe.