Why don't lambda expressions require <functional>, but function<void()> does? - c++

I have some code use lambda expression like it:
#include <vector>
#include <algorithm>
int main(){
std::vector<int> vi={3,1};
std::sort(vi.begin(),vi.end(),[](int x,int y){
return x<y;
});
return 0;
}
Which doesn't require #include< functional> to compile, but if I use a variable to store the lambda function:
#include <vector>
#include <algorithm>
#include <functional>
int main(){
std::vector<int> vi={3,1};
std::function<void()> compf=[](int x,int y){
return x<y;
};
std::sort(vi.begin(),vi.end(),compf);
return 0;
}
Then I need to include <functional> to compile, why? And why sort() doesn't also include <functional> already?

Because a lambda expression is a core language feature, provided by the compiler. std::function is a library feature, implemented in code. Note that you don't need to include anything to store the lambda in a variable.
auto f = [](int x, int y){ return x < y; };
You only need to include <functional> if you plan to store it in a std::function (because that's where it's implemented).
You seem to be under the impression that the type of a lambda is a std::function. It is not. Every lambda expression has its own unique, unnameable type. I captured that type above, with auto. std::function is a more general type that can store any function-like object with the appropriate signature. For example, I can create a std::function<int(int,int)> object, and assign to it a normal function, a function object, and a lambda.
#include <functional>
int minus_func(int a, int b) { return a - b; }
struct plus_t {
int operator()(int a, int b) const { return a + b; }
};
int main() {
auto mult_lambda = [](int a, int b) { return a * b; };
std::function<int(int,int)> func;
func = minus_func;
func = plus_t{};
func = mult_lambda;
}
There's also a cost to that generality, in the form of dynamic allocation, and indirection. Whereas using a lambda through a variable of its actual type is very often inlined.

lambda functions are part of the language -- independent of any libraries.
std::function, on the other hand, is part of the standard library and is defined in the standard library header file functional.
Hence, use of
std::sort(vi.begin(),vi.end(),[](int x,int y){
return x<y;
});
does not require functional to be #included while use of
std::function<void()> compf=[](int x,int y){
return x<y;
};
std::sort(vi.begin(),vi.end(),compf);
requires functional to be #included.

Related

Different stack depth for lambdas and regular functions in C++?

Consider a normal recursive function:
#include <iostream>
#include <functional>
void f(unsigned long long int x) {
std::cout << x << "\n";
if(x < 1e9)
f(x+1);
}
int main() {
f(1);
return 0;
}
This terminates at 43033.
Now consider a recursive lambda:
#include <iostream>
#include <functional>
int main() {
std::function<void(int)> g = [&g](unsigned long long int x) {
std::cout << x << "\n";
if(x < 1e9)
g(x+1);
};
g(1);
return 0;
}
This terminates at a much lower stack depth of 11736.
Why do lambdas have a lower max stack depth?
(Compiling with g++ (GCC) 5.4.0, with -std=c++14 -Wall)
Also note that compiling with -O3 optimization allows for practically infinite recursion depth, but the lambda still terminates at 25k.
EDIT: Following #Yakk, here are results with the Y-combinator:
#include <iostream>
#include <functional>
using namespace std;
template <typename T, typename R>
function<R(T)> Y(function<function<R(T)>(function<R(T)>)> f) {
// Y f = f (λx.(Y f) x)
return f([=](T x) { return Y(f)(x); });
}
int main() {
using fg = function<void(int)>;
function<fg(fg)> sg = [](fg g) {
return [g](unsigned long long int x) {
std::cout << x << "\n";
if(x < 1e9)
g(x+1);
};
};
Y(sg)(1);
return 0;
}
This terminates at 4781 and 9221 with and without -O3 respectively.
std function does not mean the same thing as lambda. A std function is an object capable of storing some lambdas, or a function pointer, or a pointer to member function, or a pointer to member data, or almost any object that overrides operator() compatibly.
When you store a lambda within a std function, there is some overhead. Not much, but some. Some of this overhead may show up as using the stack more (and the overhead will be larger in unoptimized builds).
You can more directly recurse using a lambda by using the y combinator, but even there you'll be passing a reference-to-self as a parameter, and unless the recursion is eliminated by the optimizer it will probably use more stack. (A highly tweaked optimizer could notice that a stateless lambda reference argument could be eliminated, but that seems tricky to work out).

Problems adapting member functions in Phoenix

I use BOOST_PHOENIX_ADAPT_FUNCTION all the time in Spirit. I'd like to be able to adapt member functions for all of the same reason. However, I get compile errors if I do something like this:
struct A { int foo(int i) { return 5*i; }};
BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, &A::foo, 2)
Is there an easy way to adapt a member function? Note that I can't just store a bind expression in an auto because I am on VC2008. How come it doesn't just work like in bind and function?
Thanks,
Mike
The BOOST_PHOENIX_ADAPT_FUNCTION(RETURN,LAZY_NAME,FUNC,N)is really simple. It just creates a functor with a templated operator() that returns RETURN and has N template parameters. In its body it simply invokes FUNC(PARAMETERS...). But &A::foo is not directly callable, and so your error occurs. You can use:
BOOST_PHOENIX_ADAPT_FUNCTION(int,AFoo,boost::mem_fn(&A::foo),2)
Running on Coliru
#include <iostream>
#include <boost/phoenix.hpp>
#include <boost/phoenix/function.hpp>
#include <boost/mem_fn.hpp>
struct A {
A(int f) : f_(f) {}
int foo(int i) {
return f_*i;
}
private:
int f_;
};
BOOST_PHOENIX_ADAPT_FUNCTION(int,AFoo,boost::mem_fn(&A::foo),2)
int main() {
using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;
A instance(5);
std::cout << AFoo(arg1,arg2)(&instance, 2) << std::endl;
}
Starting with the simplest:
How come it doesn't just work like in bind and function?
Because the macro is designed for functions, not member functions. Pointer-to-member-functions are very different from function pointers, so that's the end of the road.
In your example, A::foo doesn't actually need to be an instance method (non-static member function), so just add static (and an implicit parameter) and be done:
struct A {
static int foo(int i) {
return 5*i;
}
};
BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, A::foo, 1)
Let's assume, though, that you did want to have the non-static member function. For this reason, let's add a little state to the A type:
struct A {
A(int f) : f_(f) {}
int foo(int i) { return f_*i; }
private:
int f_;
};
Phoenix provides the following approaches to create lazy actors calling member functions:
use the ->* operator. This leads to slightly obscure syntax:
A instance(9);
int direct = (arg1->*&A::foo)(arg2)
(&instance, 7); // direct == 63
alternatively, you can use a bind expression (note: boost::phoenix::bind here!), which might just be what you were looking for:
int with_bind = bind(&A::foo, arg1, arg2)
(&instance, 7);
Now, of course, you might be looking to assign the lazy functor to a variable. In that respect, I can only recommend BOOST_AUTO:
BOOST_AUTO(afoo, (arg1->*&A::foo)(arg2));
return afoo(&instance, 2);
Which works like a charm.
Full C++03 Sample
See it Live on Coliru
struct A {
A(int f) : f_(f) {}
int foo(int i) {
return f_*i;
}
private:
int f_;
};
#include <boost/phoenix.hpp>
#include <boost/phoenix/function.hpp>
#include <cassert>
int main() {
using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;
A instance(9);
int direct = (arg1->*&A::foo)(arg2)
(&instance, 7);
int with_bind = bind(&A::foo, arg1, arg2)
(&instance, 7);
assert(direct == with_bind);
BOOST_AUTO(afoo, (arg1->*&A::foo)(arg2));
return afoo(&instance, 2);
}

How can I use a boost function to transform the parameter types?

I want to create a boost function object of the following signature:
void (int, boost::uuid);
However, I would like to bind it to a function of the following form:
void (SomeType, boost::uuid)
Where the SomeType argument comes from another function call, so that if I were to call it straight out it would look like:
SomeType myOtherFunction(int);//Prototype
...
myFunction(myOtherFunction(int), myUUID);
In other words, I want the top level function object to completely hide the concept of SomeType and the call to myOtherFunction from the user. Is there a way to do this with one or more boost::function objects created with boost::bind calls?
Functional composition: Live On Coliru
#include <boost/uuid/uuid.hpp>
struct SomeType {};
SomeType myOtherFunction(int) { return SomeType(); }
void foo(SomeType, boost::uuids::uuid) {}
#include <boost/bind.hpp>
#include <boost/function.hpp>
int main()
{
boost::function<void(int, boost::uuids::uuid)> composed;
composed = boost::bind(foo, boost::bind(myOtherFunction, _1), _2);
}
Anyways, in c++11 you'd write [](int i, uuid u) { return foo(myOtherFunction(i), u); } of course

How do I std::bind with more than 4 placeholders in Visual C++?

I want to bind a member to store a function object outside of the class instance. Howeber, in VS2012 this only works up to placeholders::_4, then it starts popping up with errors. Take this for example:
#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int method(int a,int b,int c,int d,int e)
{
return a;
}
};
int main()
{
std::function<int (int,int,int,int,int)> obj;
A a;
// error: no instance of overloaded function "std::bind" matches the argument list
obj = std::bind(&A::method,&a,_1,_2,_3,_4,_5);
std::cout << obj(1,2,3,4,5);
return 0;
}
The above code compiles fine on GCC 4.7.2 but causes the above-mentioned error in Visual Studio 2012. Are there any workarounds, is this a bug in VC++ or am I doing something dodgy here?
Since Visual Studiio does not support variadic templates this is solved by a define.
You can set a define _VARIADIC_MAX to the amount of params you need. Do this in your projects settings to that it is set before any system headers are included.
But keep in mind that setting this value to a large number will increase compile times.
One alternative would be to use a lambda instead like this:
#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int method(int a, int b, int c, int d, int e)
{
return a;
}
};
int main()
{
std::function<int(int, int, int, int, int)> obj;
A a;
obj = [&a](int b, int c, int d, int e, int f){return a.method(b,c,d,e,f); };
std::cout << obj(1, 2, 3, 4, 5);
return 0;
}
edit: it seems like this won't work either without following #mkaes answer, since apparently the definition of the std::function depends on it.

C++ - binding function

I have some (library API, so I can't change the function prototype) function which is written the following way:
void FreeContext(Context c);
Now, at some moment of my execution I have Context* local_context; variable and this is also not a subject to change.
I wish to use boost::bind with FreeContext function, but I need to retrieve Context from local variable Context*.
If I write my code the following way, the compiler says it's "illegal indirection":
boost::bind(::FreeContext, *_1);
I managed to solve this problem the following way:
template <typename T> T retranslate_parameter(T* t) {
return *t;
}
boost::bind(::FreeContext,
boost::bind(retranslate_parameter<Context>, _1));
But this solution doesn't seem really good to me. Any ideas on how to solve this using something like *_1. Maybe writing a small lambda function?
You could use Boost.Lambda which have overloaded the * operator for _n.
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <algorithm>
#include <cstdio>
typedef int Context;
void FreeContext(Context c) {
printf("%d\n", c);
}
int main() {
using boost::lambda::bind;
using boost::lambda::_1;
Context x = 5;
Context y = 6;
Context* p[] = {&x, &y};
std::for_each(p, p+2, bind(FreeContext, *_1));
return 0;
}
Use either Boost.Lambda or Boost.Phoenix to have a working operator* on a placeholder.
You can also place the Context pointer in a shared_ptr with a custom deleter:
#include <memory> // shared_ptr
typedef int Context;
void FreeContext(Context c)
{
printf("%d\n", c);
}
int main()
{
Context x = 5;
Context* local_context = &x;
std::shared_ptr<Context> context(local_context,
[](Context* c) { FreeContext(*c); });
}
Not sure this is relevant though. Good luck!