Can this be considered a valid C++ variant of a lambda function? - c++

Referencing What is a lambda (function)?
I noticed there was not a C++ solution among the interesting answers.
So I played a little with a C++ solution.
I wonder if this code is a valid C++ version of the adder() function ?
//to accept the 19 i need a rvalue ref.
auto adder = [](int&& x) { auto rv = [&x](int y) {return x + y; };return rv;};
//the similar line to most examples:
auto add5 = adder(19);
std::cout<<"val : "<<add5(4);

Yes thats a completely valid lambda expression.
It's not apparent what is the advantage of nesting is in your example. Though consider a function:
int add(int a, int b) { return a + b; }
When you want to bind a particular value to one of the parameters to get a function you can call with one parameter you can use a lambda expression. And if you want to bind different values you can use a nested lambda expression:
auto add_x = [](int x){ return [x](int y){ return add(x,y); };};
auto add_3 = add_x(3);
auto add_7 = add_x(7);
std::cout << add_3(5); // prints 8
std::cout << add_7(5); // prints 12

Related

auto variable declaration without definition

I was wondering if there's an elegant solution for the following issue:
Let's say I'd like to have a variable holding a value with a pretty complex type and would the compiler to automatically infer it's type, but declare first and give value later in the code because of initialization in an if statement.
For example:
{
auto a;
if (some predicate)
a = init_a(1);
else
a = init_a(2);
}
Obviously this code doesn't compile, but the I think that the compiler has all the information it needs to infer the type.
If 'a' was just an int, this was not a problem, but if the type is a complex template, I don't want to have to write it (or in some cases even know it).
Also, i wouldn't want to call the default constructor of a and then write over it.
Possible solutions:
Template the type of 'a'.
initialize 'a' using a lambda and move the predicate into the lambda.
Just write the type of 'a' instead auto.
Use a void pointer/shared_ptr and then init 'a' on the heap.
Each of these has its own drawbacks.
Is there a more elegant solution for it?
The compiler doesn't have infinite lookahead what is happening further on in the code. It only knows what's happening at the current statement. Therefore it can't deduce any types without an initializer.
If you don't know the return-type of init_a then you could use decltype:
decltype(init_a(1)) a;
You can also use a lambda call to initialize the variable:
auto a = [ /* Captures needed for the condition... */ ]()
{
if (some_condition)
return init_a(1);
else
return init_a(2);
}(); // Call the lambda immediately
Or, as mentioned in many comments, use the ternary conditional expression:
auto a = some_condition ? init_a(1) : init_a(2);
There's a technique called "Immediately Invoked Lambda Expression" that is using lambda to initialize a variable in a complex way. Using this approach your a can be const which improves const-correctness. More details here.
For a simple binary predicate, consider just using the ternary operator:
struct A { int a; };
A initA(int a) { return A{a}; }
bool somePredicate(int input) { return input == 42; }
int main() {
const auto input = 42;
const auto a = somePredicate(input) ? initA(1) : initA(2);
}
for more complex initialization logic (beyond a binary case), wrap the initialization logic in a lambda:
struct A { int a; };
A initA(int a) { return A{a}; }
bool somePredicate(int input) { return input == 42; }
int main() {
const auto input = 42;
const auto a = []() {
if (somePredicate(input)) { return initA(1); }
else if (input == 100) { return initA(100); }
else { return initA(2); }}();
}
Both these approaches come with additional possibility of making the variable to be initialized const.
If the return types of your lambda are different but convertible to some type then you can force the return type (note the -> is mandatory when specifying a return type):
auto a = [=]() -> ConvertedType {
if (some_predicate) {
return CovertibleType1(1);
} else if (other_predicate) {
return ConvertibleType2(2);
}
return ConvertibleType3(3);
}();
Though I realize this basically defeats the auto declaration...

std::bind won't accept an std::cref of a bind-placeholder - why?

I try to pass a method as a parameter function, which itself takes a parameter, by using std::cref, but somehow I cannot get it right. What is wrong?
struct node
{
void get(int &i){
i = x;
}
int x, z;
void foo(std::function<void(int&)>t){
t(z);
}
void bar(){
x = 7;
z = 10;
foo(std::bind(&node::get, this, std::cref(_1)));
cout<< "z:" << z << std::endl; //Here is expected that z is changed to 7
}
};
std::bind can only process placeholders directly as parameters: std::bind(…, _1, …).
std::cref(_1) wraps the placeholder in a std::reference_wrapper. bind doesn't recognize it as a placeholder anymore, and tries to pass it directly to the bound function, as it would do with any other non-placeholder parameter.
To work around this and other limitations of bind, use a lambda:
foo([this](int &x){return get(std::ref(x));});
I've replaced cref with ref here, because get() expects a non-const reference. You can't use cref here, with or without the lambda. (Note that std::ref(x) is equivalent to x here, and is used instead of x for demonstration purposes only.)

Is it possible to access (read only) the variables captured by a lambda?

Is it possible to access (read only) the variables captured by a lambda?
This doesn't work:
std::function<double (const double)> plus (const double a) {
return [a] (const double b) -> double {
return a+b;
};
}
auto plus5 = plus(5);
cout << plus5.a << endl;
auto plus( double a ) {
using R = struct {
double a;
double operator()(double b)const{return b+a;}
};
return R{std::move(a)};
}
live example.
Please note that a std::function is not a lambda, and lambda is not a std::function. They work with each other, but using one term to refer to the other is the opposite of helpful.
This is not how a lambda should be used.
The interface of a lambda is its function signature. Its captures should be considered an implementation detail and not be visible to the user.
If you want explicit access to the captures, write your own function object and expose the respective data members accordingly:
struct MyPlus {
double a;
MyPlus(double x) : a(x) {}
double operator()(const double b)
{
return a+b;
}
};
auto plus5 = MyPlus(5);
std::cout << plus5.a;
"Definitely not after storing it in a std function. Without that, I could do it with a horrible (yet legal) hack in C++17. But I would be a horrible person to tell you how, because you might use it." – Yakk
Well let's relieve Yakk's karma; here's a proof of concept of a C++14 solution which you definitely don't want to let loose in the wild:
auto magic = [a, b](auto &&... args) mutable -> decltype(auto) {
return makeOverload(
// Capture access boilerplate
[&](cap_<0>) -> auto& { return a; },
[&](cap_<1>) -> auto& { return b; },
// Actual function
[&](int p) {
return "[" + std::to_string(a) + ", " + b + "](" + std::to_string(p) + ")";
}
)(std::forward<decltype(args)>(args)...);
};
makeOverload takes any number of functors and blends them into a single one. I borrowed the idea from this blog post, with help from the comment section to make it actually work.
The resulting functor is used to tag-dispatch between the cap<N> tags and the actual parameters of the function. Thus, calling magic(cap<0>) causes it to spit out the corresponding captured variable, that is a. The actual behaviour of the function is, of course, still accessible with a normal call to magic(123).
As a bonus, the outer lambda is mutable, and the capture accessors return by reference: you actually have read-write access to the captured variables!
You can observe and interact with this creature in its natural habitat on Coliru right here.

What is this C++14 construct called which seems to chain lambdas?

This is a follow-up question on this one: Lambda-Over-Lambda in C++14, where the answers explain the code.
It is about a lambda that creates another lambda which when called, calls the passed lambda and passes the return value to the original lambda, thus returning a new instance of the second lambda.
The example shows how this way lambdas can be chained.
Copy from the original question:
#include <cstdio>
auto terminal = [](auto term) // <---------+
{ // |
return [=] (auto func) // | ???
{ // |
return terminal(func(term)); // >---------+
};
};
auto main() -> int
{
auto hello =[](auto s){ fprintf(s,"Hello\n"); return s; };
auto world =[](auto s){ fprintf(s,"World\n"); return s; };
terminal(stdout)
(hello)
(world) ;
return 0;
}
Is there already a name for this construct and if not what should it be called?
Does it resemble constructs in other languages?
Remark: I'm not interested in whether it is actually useful.
I looked around a bit and turns out the main functionality is reordering the function calls as explained in the answers to the original question.
So world(hello(stdout)); is rewritten to terminal(stdout)(hello)(world); which more generally could be written as compose(stdout)(hello)(world);.
In Haskell this would written as world . hello $ stdout and is called function composition.
In clojure it would be (-> stdout hello world) and is called the "thread-first" macro
I think it is only useful with decent partial application which lambdas provide a little bit, so we could have compose(4)([](int x){ return x + 7; })([](int x){ return x * 2; })([](int x){ return x == 22; }); which should return true if my calculation (and blind coding) is any good.
or to emphasize the partial application:
auto add7 = [](int x){ return x + 7; };
auto dbl = [](int x){ return x * 2; };
auto equal22 = [](int x){ return x == 22; };
assert(compose(4)(add7)(dbl)(equals22));
1 major issue with this implementation is probably that the result can't be evaluated because in the end a lambda is returned, so the construction in this answer might be better suited (function separated by comma instead of parenthesis).
terminal(x) returns an applicator that method-chains its return value into terminal for repeated invocation.
But we could instead generalize it.
Suppose you have a function F. F takes an argument, and stuffs it on a stack.
It then examines the stack. If the top of the stack, evaluated on some subset of the stack, would work for invocation, it does it, and pushes the result back onto the stack. In general, such invocation could return a tuple of results.
So:
F(3)(2)(add)(2)(subtract)(7)(3)(multiply)(power)
would evaluate to:
((3+2)-2)^(7*3)
Your terminal does this with 0 argument functions (the first argument) and with 1 argument functions (every argument after that), and only supports 1 return value per invocation.
Doing this with a lambda would be tricky, but what I described is doable in C++.
So one name for it would be stack-based programming.
As far as I know there is no "official" name, yet.
Suggestions:
Lambda chain
Lambda sausage
Curry sausage

C++ lambda function access write violation

I'm learning how to use C++ lambda functions along with <functional>'s function class. I am trying to solve this Code Golf as practice (challenge is Curry for Dinner)
I have this function:
// This creates a function that runs y a number of
// times equal to x's return value.
function<void()> Curry(function<int()> x, function<void()> y)
{
return [&]() {
for (int i = 0; i < x(); i++)
{
y();
}
};
}
To test this I have this code in my main():
auto x = [](){ return 8; };
auto y = [](){ cout << "test "; };
auto g = Curry(x, y);
This throws Access violation reading location 0xCCCCCCCC. in Functional.h.
Yet when I copy-paste the lambda function from inside Curry() to inside my main like this:
auto x = [](){ return 8; };
auto y = [](){ cout << "test "; };
auto g = [&]() {
for (int i = 0; i < x(); i++)
{
y();
}
};
I get the code running as expected. Why does this happen?
You have a few problems.
Here:
return [&]() {
you capture by reference. Any variables you capture has to have a lifetime that exceeds your own. It means that running the lambda becomes undefined behavior after the variables you capture&use lifetime ends. As you are returning this lambda, and capturing local state, this seems likely to happen. (Note I said variables -- due to a quirk in the standard, [&] captures variables not the data referred to by variables, so even capturing & function arguments by [&] is not safe. This may change in future revisions of the standard... There are neat optimizations that this particular set of rules allow in lambda implementations (reduce [&] lambdas to having 1 pointer worth of state(!)), but it also introduces the only case in C++ where you have a reference to a reference variable in effect...)
Change it to
return [=]() {
and capture by-value.
Or even:
return [x,y]() {
to list your captures explicitly.
When using a lambda which does not outlive the current scope, I use [&]. Otherwise, I capture by value explicitly the stuff I am going to use, as lifetime is important in that case.
Next:
for (int i = 0; i < x(); i++)
you run x once for every loop iteration. Seems silly!
Instead:
auto max = x();
for (auto i = max; i > 0; --i)
which runs max times, and as it happens works if the return value of x was changed to unsigned int or whatever.
Or:
int max = x();
for (int i = 0; i < max; ++i)
which both runs x once, and behaves better if x returns -1.
Alternatively you can use the obscure operator -->:
int count = x();
while( count --> 0 )
if you want to make your code unreadable. ;)