Trying to understand lambdas in C++, what I do not understand is this:
int multiplier = 5;
auto timesFive = [multiplier](int a) { return a * multiplier; };
std::cout << timesFive(2) << '\n'; // Prints 10
multiplier = 15;
std::cout << timesFive(2) << '\n'; // Still prints 2*5 == 10 (???) - Should it be 30?
When the program calls the timesFive() the second time, I expect the result to be 30. But why is the result Still prints 2*5 == 10, not prints 2*15 == 30? Perhaps the lambda function somehow cannot track the value of multiplier, even though we have already tried to capture it?
And what is the way to get the desired result?
You captured multiplier by value, which means it was copied into the lambda. You need to capture it by reference:
int multiplier = 5;
auto timesFive = [&multiplier](int a) { return a * multiplier; };
std::cout << timesFive(2);
multiplier = 15;
std::cout << timesFive(2);
Lambdas are syntatic sugar for an unnamable class and the instance thereof. Sometimes expanding your code out to what this unnamable class can help understanding what is going on.
[ capture_list ]( arg_list ) -> return_value_clause_opt { body };
becomes very roughly (pseudo-code):
struct anonymous_type {
capture_list;
auto operator()( arg_list ) const -> return_value_clause_opt {
body
}
anonymous_type( capture_list_in ):capture_list(capture_list_in) {}
};
If you list a variable in capture_list by its plain name, it is copied into a copy within the anonymous class.
So your timesFive became
struct __secret_name__ {
int multiplier;
int operator()(int a) const { return a*multiplier; }
};
int multiplier = 5;
auto timesFive = __secret_name__{multiplier};
It should be pretty clear that changing multiplier in the above code won't change the behavior of timesFive.
If you put a & in front of the name, a non-const reference is placed within the anonymous class.
struct __secret_name__ {
int& multiplier;
int operator()(int a) const { return a*multiplier; }
};
int multiplier = 5;
auto timesFive = __secret_name__{multiplier};
now, changing multiplier will change the behavior of timesFive, because timesFive holds a reference to multiplier, not a copy of it.
Some details skipped above for brevity. The name __secret_name__ is only for exposition. The member variables of the lamba are not actually public. The lambda being trivially constructible is implementation defined even if its data is. Etc.
Related
In C++ Primer the book says if we want to change the variable captured by value, we should add "mutable" ketword behind the parameter list. However, I found some problems when I write some codes to test this rule.
First I write the codes below:
//case1:
int val = 5;
auto f1 = [val]() mutable {return ++val;};
cout << f1() <<endl;
//case2:
int val = 5;
auto f2 = [val]() mutable {return val+5;};
cout << f2() <<endl;
I get correct return value as expected. The first block of codes returns 6 and the second returns 10.
However, as I want to test whether the "mutable" keyword is really useful as descirbed in the book, I delete the "mutable" keyword in both blocks of codes.
//case1:
int val = 5;
auto f1 = [val]() {return ++val;};
cout << f1() <<endl;
//case2:
int val = 5;
auto f2 = [val]() {return val+5;};
cout << f2() <<endl;
As expected, case1 compilation failed. However, case2 can still compile success and return 10! I got confused and I don't know what happened behind the case2. From the case1, I see the "mutable" keyword really useful. However, from the case2, althougth there's not a "mutable", I can also change the value of the variable 'val'. Who can tell me what happened? Is there something I ignore?
int val = 5;
auto f1 = [val]() mutable {return ++val;};
cout << f1() <<endl;
is equivalent to:
int val = 5;
struct f1_t {
mutable int val;
f1_t(int v): val(v) {}
int operator()() const {return ++val;}
};
auto f1 = f1_t(val);
cout << f1() << endl;
++val is increasing val itself which would change val. But if you do val + 5, everything that happens is that a temporary int object of the value 10 is created and then returned, but val actually never changes so its perfectly valid.
I'm trying to use static array which size needs to be determined by given template values. However size will be constant across program runtime - thats why I decided not to use std::vector.
template<uint32_t BAR_WIDTH>
class Bar
{
//do_stuff...
Foo mapper[ [&]()->int{ uint32_t tmp = BAR_WIDTH / Foo:FOO_EDGE; return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1; }; ];
};
FOO_EGDE is const static value. IDE gives me a hint that
Array size expression must have an integer type instead of int(*)()
I wonder if I can make it work this way without using std::vector. Any advice is welcomed and appreciated.
The problem is, that you are using a lambda for determining the size of the array. If you leave it off and just use the ternary operator, it works:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[z ? x : y];
return 0;
}
Ideone
As opposed to:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[[&]() -> int { return z ? x : y; }];
return 0;
}
Ideone
As described here, lambda expressions can't be constexpr yet, and you can only declare the size of an array with a constexpr value (even then, you are not trying to invoke declared lambda (to invoke it - () is required at the end of declaration).
To work around such problem, you could use a private static constexpr method, and use the return value of it, for the array size declaration:
static constexpr uint32_t GetArraySize ()
{
uint32_t tmp = BAR_WIDTH / Foo::FOO_EDGE;
return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1;
}
Foo mapper[GetArraySize ()];
Lambdas are an awesome way to create reusable code inside a function/method without polluting the parent class. They're a very functional replacement for C-style macros most of the time.
However, there's one bit of syntactic sugar from macros that I can't seem to replicate with a lambda, and that's the ability to exit from the containing function. For example, if I need to return while checking the range of a series of ints, I can do that easily with a macro:
const int xmin(1), xmax(5);
#define CHECK_RANGE(x) { if((x) < xmin || (x) > xmax) return false; }
bool myFunc(int myint) {
CHECK_RANGE(myint);
int anotherint = myint + 2;
CHECK_RANGE(anotherint);
return true;
}
Obviously this is an oversimplified example, but the basic premise is that I'm performing the same check over and over on different variables, and I think it's more readable to encapsulate the check and related exits. Still, I know that macros aren't very safe, especially when they get really complex. However, as far as I can tell, trying to do the equivalent lambda requires awkward additional checks like so:
const int xmin(1), xmax(5);
auto check_range = [&](int x) -> bool { return !(x < xmin || x > xmax); };
bool myFunc(int myint) {
if(!check_range(myint)) return false;
int anotherint = myint + 2;
if(!check_range(anotherint)) return false;
return true;
}
Is there a way to do this with a lambda? Or am I missing some alternative solution?
Edit: I recognize that returning from inside a macro is generally a bad idea unless significant precautions are taken. I'm just wondering if it's possible.
You are correct--there's no way to return from the caller from inside a lambda. Since a lambda can be captured and stored to be called later, from inside an arbitrary caller, doing so would result in unpredictable behavior.
class Foo
{
Foo(std::function<void(int)> const& callMeLater) : func(callMeLater) {}
void CallIt(int* arr, int count)
{
for (index = count; index--;)
func(count);
// do other stuff here.
}
std::function<void(int)> func;
};
int main()
{
auto find3 = [](int arr)
{
if (arr == 3)
return_from_caller; // making up syntax here.
};
Foo foo(find3);
};
Is there a way to do this with a lambda?
Not exactly like the macro but your lambda, instead of returning a bool, can throw a special exception (of type bool, by example)
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
and the function myFunc() can intercept this special type
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
For a single check_range() call, this is (I suppose) a bad idea; if you have a lot of calls, I suppose can be interesting.
The following is a full working example
#include <iostream>
constexpr int xmin{1}, xmax{5};
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
int main ()
{
std::cout << myFunc(0) << std::endl; // print 0
std::cout << myFunc(3) << std::endl; // print 1
std::cout << myFunc(7) << std::endl; // print 0
}
No better way to do this than just to use the return value of the lambda and then return from the calling function. Macros are ew for this.
As it stands in C++, that is the idiomatic way to exit from a function that uses another condition to determine whether or not to exit.
Not C++11, but people have hacked C++2a coroutines to basically do this.
It would look a bit like:
co_await check_range(foo);
where the co_await keyword indicates that in some cases, this coroutine could return early with an incomplete result. In your cases, this incomplete result would be non-resumabable error.
The playing around I saw was with optionals, and required using a shared ptr, but things may improve before it is standardized.
I am new to c++. I have to calculate a value via equation and store that value each time whenever the function is being called. I have created an array of size 10 and calculated myValue then tried to store that value. Is this right way to do so? Will it work in way that each time whenever the function is called it will calculate and store myValue and use that value n[i-1] in the next call to calculate my value n[i]. Let's say in 1st call myvalue is 0.5. In next call it would be myValue = (1-0.3)* 0.5. Will it store all 10 values in 10 calls and use the last stored value to calculate myValue. It is not showing me any error when I am compiling it but still I have doubt.
static double
CalculatemyValue(Node* ch)
{
float gamma=0.3;
double myValue = 0.0;
int n[10];
int i = 0;
n[i] = myValue;
myValue = ((1-gamma)*n[i-1]) //previous value
return myValue;
}
In the given code
static double
CalculatemyValue(Node* ch)
{
float gamma=0.3;
double myValue = 0.0;
int n[10];
int i = 0;
n[i] = myValue;
myValue = ((1-gamma)*n[i-1]) //previous value
return myValue;
}
… the array n is a local automatic variable. It's created anew each time execution reaches the declaration, and destroyed when execution leaves the block. No information is retained between calls.
One good way to retain state between calls is to make the function a member function of a class, whose data members constitute the state you want to keep, e.g. like this:
class Power_sequence
{
private:
double gamma_;
double value_;
public:
auto gamma() const -> double { return gamma_; }
void advance() { value_ *= 1 - gamma_; }
auto current() const -> double { return value_; }
auto next()
-> double
{
double const result = current();
advance();
return result;
}
Power_sequence( double const gamma = 0.3 )
: gamma_( gamma )
, value_( 1.0 )
{}
};
… which you would use like this:
Power_sequence seq;
for( int i = 1; i <= 42; ++i )
{
cout << seq.next() << endl;
}
Disclaimer: above code not checked by a compiler.
Another way is to pass the state as an explicit argument to the function.
I have the following Python snippet that I would like to reproduce using C++:
from itertools import count, imap
source = count(1)
pipe1 = imap(lambda x: 2 * x, source)
pipe2 = imap(lambda x: x + 1, pipe1)
sink = imap(lambda x: 3 * x, pipe2)
for i in sink:
print i
I've heard of Boost Phoenix, but I couldn't find an example of a lazy transform behaving in the same way as Python's imap.
Edit: to clarify my question, the idea is not only to apply functions in sequence using a for, but rather to be able to use algorithms like std::transform on infinite generators. The way the functions are composed (in a more functional language like dialect) is also important, as the next step is function composition.
Update: thanks bradgonesurfing, David Brown, and Xeo for the amazing answers! I chose Xeo's because it's the most concise and it gets me right where I wanted to be, but David's was very important into getting the concepts through. Also, bradgonesurfing's tipped Boost::Range :).
Employing Boost.Range:
int main(){
auto map = boost::adaptors::transformed; // shorten the name
auto sink = generate(1) | map([](int x){ return 2*x; })
| map([](int x){ return x+1; })
| map([](int x){ return 3*x; });
for(auto i : sink)
std::cout << i << "\n";
}
Live example including the generate function.
I think the most idiomatic way to do this in C++ is with iterators. Here is a basic iterator class that takes an iterator and applies a function to its result:
template<class Iterator, class Function>
class LazyIterMap
{
private:
Iterator i;
Function f;
public:
LazyIterMap(Iterator i, Function f) : i(i), f(f) {}
decltype(f(*i)) operator* () { return f(*i); }
void operator++ () { ++i; }
};
template<class Iterator, class Function>
LazyIterMap<Iterator, Function> makeLazyIterMap(Iterator i, Function f)
{
return LazyIterMap<Iterator, Function>(i, f);
}
This is just a basic example and is still incomplete as it has no way to check if you've reached the end of the iterable sequence.
Here's a recreation of your example python code (also defining a simple infinite counter class).
#include <iostream>
class Counter
{
public:
Counter (int start) : value(start) {}
int operator* () { return value; }
void operator++ () { ++value; }
private:
int value;
};
int main(int argc, char const *argv[])
{
Counter source(0);
auto pipe1 = makeLazyIterMap(source, [](int n) { return 2 * n; });
auto pipe2 = makeLazyIterMap(pipe1, [](int n) { return n + 1; });
auto sink = makeLazyIterMap(pipe2, [](int n) { return 3 * n; });
for (int i = 0; i < 10; ++i, ++sink)
{
std::cout << *sink << std::endl;
}
}
Apart from the class definitions (which are just reproducing what the python library functions do), the code is about as long as the python version.
I think the boost::rangex library is what you are looking for. It should work nicely with the new c++lambda syntax.
int pipe1(int val) {
return 2*val;
}
int pipe2(int val) {
return val+1;
}
int sink(int val) {
return val*3;
}
for(int i=0; i < SOME_MAX; ++i)
{
cout << sink(pipe2(pipe1(i))) << endl;
}
I know, it's not quite what you were expecting, but it certainly evaluates at the time you want it to, although not with an iterator iterface. A very related article is this:
Component programming in D
Edit 6/Nov/12:
An alternative, still sticking to bare C++, is to use function pointers and construct your own piping for the above functions (vector of function pointers from SO q: How can I store function pointer in vector?):
typedef std::vector<int (*)(int)> funcVec;
int runPipe(funcVec funcs, int sinkVal) {
int running = sinkVal;
for(funcVec::iterator it = funcs.begin(); it != funcs.end(); ++it) {
running = (*(*it))(running); // not sure of the braces and asterisks here
}
return running;
}
This is intended to run through all the functions in a vector of such and return the resulting value. Then you can:
funcVec funcs;
funcs.pushback(&pipe1);
funcs.pushback(&pipe2);
funcs.pushback(&sink);
for(int i=0; i < SOME_MAX; ++i)
{
cout << runPipe(funcs, i) << endl;
}
Of course you could also construct a wrapper for that via a struct (I would use a closure if C++ did them...):
struct pipeWork {
funcVec funcs;
int run(int i);
};
int pipeWork::run(int i) {
//... guts as runPipe, or keep it separate and call:
return runPipe(funcs, i);
}
// later...
pipeWork kitchen;
kitchen.funcs = someFuncs;
int (*foo) = &kitchen.run();
cout << foo(5) << endl;
Or something like that. Caveat: No idea what this will do if the pointers are passed between threads.
Extra caveat: If you want to do this with varying function interfaces, you will end up having to have a load of void *(void *)(void *) functions so that they can take whatever and emit whatever, or lots of templating to fix the kind of pipe you have. I suppose ideally you'd construct different kinds of pipe for different interfaces between functions, so that a | b | c works even when they are passing different types between them. But I'm going to guess that that's largely what the Boost stuff is doing.
Depending on the simplicity of the functions :
#define pipe1(x) 2*x
#define pipe2(x) pipe1(x)+1
#define sink(x) pipe2(x)*3
int j = 1
while( ++j > 0 )
{
std::cout << sink(j) << std::endl;
}