Why is my lambda function not getting executed? - c++

I have the following function and this is called by main. But I don't see the lambda function being executed.
int LambdaTest(int x, int y, bool bLambda) {
cout << "Lambda Rxd : " << bLambda << endl;
if (bLambda) {
return x + y;
} else {
return ((x > y) ? (x - y) : (y - x));
}
}
int main() {
int x = 10, y = 30;
int val = -1;
val = LambdaTest(x, y, [](int x) -> bool {
return x > 15;
});
cout << "Lambda test 1: " << val << endl;
val = LambdaTest(x, y, [](int y) -> bool {
return y > 15;
});
cout << "Lambda test 2: " << val << endl;
return 0;
}
In this main function my expectation is that the lambda function which is passed as third parameter of the function call shall execute and return true or false.
But I don't see the right value being passed to the function body.
Is there any extra need to be done?

You have stateless lambda.
Stateless lambda can be converted to pointer to function. So your lambdas are converted into void (*)(int), and this pointer is assigned to bool what gives always true.
To call lambda "in fly" you need to add () with parameter:
val = LambdaTest(x, y, [](int x) -> bool {
return x > 15;
}(x) ); // <---
cout << "Lambda test 1: " << val << endl;
val = LambdaTest(x, y, [](int y) -> bool {
return y > 15;
}(y) ); // <---
[](){} -> bool ( /*here passed arguments */ );
Another solution is to store functor generated by lambda expression in some variable and then apply () on that object:
auto l1 = [](int x) -> bool {
return x > 15;
};
val = LambdaTest(x, y, l1(x));
cout << "Lambda test 1: " << val << endl;

Related

C++: How to make a container indexed by std::function?

For indexing I use std::unordered_map and std::map. Both of them throws compiling errors when using as follow:
std::unordered_map<std::function<bool(Ent*)>, int> var;
std::unordered_map fails due referencing deleted function
std::map fails due no < operator
The ideal solution for me would be to use a type of map, but if is a must to use another type of container, then it shouldn't be a problem
One way of having functions as container key is to wrap them into functor structure
#include <unordered_map>
#include <typeinfo>
struct FunctorSum {
int operator()(int x, int y) {
return x + y;
}
};
struct FunctorMult {
int operator()(int x, int y) {
return x * y;
}
};
int main() {
std::unordered_map<size_t, int> funcToInt;
funcToInt[typeid(FunctorSum).hash_code()] = 0;
funcToInt[typeid(FunctorMult).hash_code()] = 1;
return 0;
}
Here I used typeid as hash, but it can also be hardcoded into functor struct.
Another way is to use std::function::target_type to calculate hash of the function, which will work only with lambdas. But you can always wrap any function into lambda.
#include <iostream>
#include <functional>
using FuncType = std::function<bool(int)>;
bool x(int v) { return v == 0; }
std::string hash(FuncType f) {
return f.target_type().name();
}
int main() {
auto y = [](int v) { return v == 1; };
auto z = [](int v) { return v == 2; };
std::cout << "x: " << hash(x) << std::endl;
std::cout << "y: " << hash(y) << std::endl;
std::cout << "z: " << hash(z) << std::endl;
return 0;
}
Output
x: PFbiE
y: Z4mainEUliE_
z: Z4mainEUliE0_

Why does postfix failed and prefix work fine when pass an iterator as argument and recurse it at tail position? [duplicate]

This question already has answers here:
What is the difference between prefix and postfix operators?
(13 answers)
Closed 5 years ago.
I come across this problem accidentally.
I have thought google can solve it surely, but after searching multiple keywords, I still can't find answers, which confused me a lot.
When I use prefix at tail position, codes works fine:
template<class ContinerIterator, class F>
constexpr auto fun(ContinerIterator IteratorBegin, ContinerIterator IteratorEnd, F f)
{
switch (IteratorBegin == IteratorEnd)
{
case true: return;
case false: f(*IteratorBegin);
}
return fun(++IteratorBegin, IteratorEnd, f);
}
int main()
{
std::vector<int> a = { 1, 2, 3, 4 };
fun(std::begin(a), std::end(a), [](auto &a)->auto{a *= 2; });
for (auto v : a)
{
std::cout << v << std::endl;
}
return 0;
}
1
2
3
4
Press any key to continue . . .
Howerer, if I use postfix, IteratorBegin nerve arrives iteratorEnd and goes far and far away, so segmentfault.
template<class ContinerIterator, class F>
constexpr auto fun(ContinerIterator IteratorBegin, ContinerIterator IteratorEnd, F f)
{
switch (IteratorBegin == IteratorEnd)
{
case true: return;
case false: f(*IteratorBegin);
}
return fun(IteratorBegin++, IteratorEnd, f);
}
void test()
{
}
int main()
{
std::vector<int> a = { 1, 2, 3, 4 };
fun(std::begin(a), std::end(a), [](auto &a)->auto{a *= 2; });
for (auto v : a)
{
std::cout << v << std::endl;
}
return 0;
}
I have tried on MSVC, G++, Clang, all fails.
Here is gcc's error list:
Segmentation fault (core dumped)
Here is Clang's:
Error occurred (timeout). Try again later.
This statement
return fun(IteratorBegin++, IteratorEnd, f);
with some exceptions can be considered like
fun(IteratorBegin, IteratorEnd, f);
++IteratorBegin;
return;
So the function is always called with the same value of IteratorBegin.
From the C++ Standard (5.2.6 Increment and decrement)
1 The value of a postfix ++ expression is the value of its operand. [
Note: the value obtained is a copy of the original value —end note
]...
Consider the following simple program
#include <iostream>
void f(int x)
{
std::cout << "Inside f( x ): x = " << x << std::endl;
}
int main()
{
int x = 0;
std::cout << "Before f( x ): x = " << x << std::endl;
f(x++);
std::cout << "After f( x ): x = " << x << std::endl;
return 0;
}
Its output is
Before f( x ): x = 0
Inside f( x ): x = 0
After f( x ): x = 1
Also it will be useful to consider the following simple program
#include <iostream>
int x = 0;
void f(int x)
{
std::cout << "Local (parameter) x = " << x << std::endl;
std::cout << "Global variable ::x = " << ::x << std::endl;
}
int main()
{
f(x++);
return 0;
}
Its output is
Local (parameter) x = 0
Global variable ::x = 1
The prefix case:
return fun(++IteratorBegin, IteratorEnd, f);
says, first increment IteratorBegin by one, and then call the function fun. After that, return.
On the other hand, the postfix case:
return fun(IteratorBegin++, IteratorEnd, f);
says, first call fun(), then increment the iterator, and then return.
This means that fun() is always being called with the non-incremented iterator.
When you use postfix increment in the tail call, the recursive call does not get the incremented value of the iterator. It gets the value of the iterator before the increment is applied. Hence, the recursion is infinite. That causes stack overflow.

runtime specialization of overloaded function

This is a variant of this SO question. I have an overloaded function that takes parameters of different types and returns different types:
struct mystruct {
auto f (int x, int y) -> int;
auto f (std::string x, int y) -> float;
};
The function f needs to call itself with one of its parameters specialized a number of times.
I'd like to define a function that specializes the parameter y, that is I'd want g(z) = f(z,y). The return type of g and the type of its unique parameter z variable, but the implementation is the same in both cases.
The best implementation I could find of this situation is overloading the lambda function:
template <class F1, class F2>
struct overload_set : F1, F2
{
overload_set(F1 f1, F2 f2) : F1(f1), F2(f2) {}
using F1::operator();
using F2::operator();
};
template <class F1, class F2>
overload_set<F1, F2> overload(F1 f1, F2 f2) {
return overload_set<F1, F2>(f1, f2);
};
struct mystruct {
auto f( std::string x, int y) -> float {
return y+9.3;
}
auto f( int x, int y) -> int
{
auto g = overload (
[=]( int z ) -> int {return f(z,y);},
[=]( std::string z) -> float { return f(z,y); }
);
if ( x == 0 ) {
std::cout << g("this string") << "\n";
return 0;
}
if ( x == 1 ) return y;
return 7;
}
};
int main () {
mystruct h;
std::cout << h.f(1,4) << "\n";
std::cout << h.f(0,2) << "\n";
}
which works as expected but seems overkill. It seems that a simple preprocessor macro of the form
#define k(z) f(z,y)
would also work. Is there a good way of achieving this?
Not sure if this is what you are attempting to do but here is a working (c++14) example:
#include <iostream>
struct mystruct {
static auto f (int x, int y) -> int {
std::cout << "f(" << x << "," << y << ")" << std::endl;
auto g = [=](auto z) -> decltype(mystruct::f(z, y)) {
return mystruct::f(z, y);
};
if (x < 1)
g("end");
else
g(x - 1);
}
static auto f (std::string x, int y) -> float {
std::cout << "f(\"" << x << "\"," << y << ")" << std::endl;
}
};
int main() {
mystruct::f(10, 1);
}
Output:
f(10,1)
f(9,1)
f(8,1)
f(7,1)
f(6,1)
f(5,1)
f(4,1)
f(3,1)
f(2,1)
f(1,1)
f(0,1)
f("end",1)
Am I missing something?
This produces the same answer, and I think is a little clearer:
#include <string>
#include <iostream>
struct mystruct
{
auto f( std::string x, int y) -> float {
return y+9.3;
}
auto f( int x, int y) -> int
{
switch(x)
{
case 0: {
auto g = [=](auto...args) { return f(args..., y); };
std::cout << g("this string") << "\n";
return 0;
} break;
case 1: {
return y;
} break;
default:
return 7;
}
}
};
int main () {
mystruct h;
std::cout << h.f(1,4) << "\n";
std::cout << h.f(0,2) << "\n";
}
Maybe in reality there are more switch cases, and g needs to be hoisted above the switch statement?

c++ std::function returns unexpected value

#include <iostream>
typedef std::function<bool(int)> set;
using namespace std;
set singletonSet(int a) {
return [&] (int x) { return (a == x); };
}
bool contains(set s, int test) {
return s(test);
}
int main() {
auto first = singletonSet(5);
auto r1 = contains(first, 10);
auto r2 = contains(first, 5);
cout << r1 << " " << r2 << endl;
return 0;
}
I expect this to print 0 1 but result is 1 1
Beginner c++ labmda programmer here so sorry in advance if this is a basic error.
Don't capture a by reference, capture it by value. As-is, you're storing a dangling reference inside the lambda, and using it later leads to UB.
set singletonSet(int a) {
return [=] (int x) { return (a == x); };
// ^
}

How to pass optional arguments to a method in C++?

How to pass optional arguments to a method in C++ ?
Any code snippet...
Here is an example of passing mode as optional parameter
void myfunc(int blah, int mode = 0)
{
if (mode == 0)
do_something();
else
do_something_else();
}
you can call myfunc in both ways and both are valid
myfunc(10); // Mode will be set to default 0
myfunc(10, 1); // Mode will be set to 1
An important rule with respect to default parameter usage:
Default parameters should be specified at right most end, once you specify a default value parameter you cannot specify non default parameter again.
ex:
int DoSomething(int x, int y = 10, int z) -----------> Not Allowed
int DoSomething(int x, int z, int y = 10) -----------> Allowed
It might be interesting to some of you that in case of multiple default parameters:
void printValues(int x=10, int y=20, int z=30)
{
std::cout << "Values: " << x << " " << y << " " << z << '\n';
}
Given the following function calls:
printValues(1, 2, 3);
printValues(1, 2);
printValues(1);
printValues();
The following output is produced:
Values: 1 2 3
Values: 1 2 30
Values: 1 20 30
Values: 10 20 30
Reference: http://www.learncpp.com/cpp-tutorial/77-default-parameters/
To follow the example given here, but to clarify syntax with the use of header files, the function forward declaration contains the optional parameter default value.
myfile.h
void myfunc(int blah, int mode = 0);
myfile.cpp
void myfunc(int blah, int mode) /* mode = 0 */
{
if (mode == 0)
do_something();
else
do_something_else();
}
With the introduction of std::optional in C++17 you can pass optional arguments:
#include <iostream>
#include <string>
#include <optional>
void myfunc(const std::string& id, const std::optional<std::string>& param = std::nullopt)
{
std::cout << "id=" << id << ", param=";
if (param)
std::cout << *param << std::endl;
else
std::cout << "<parameter not set>" << std::endl;
}
int main()
{
myfunc("first");
myfunc("second" , "something");
}
Output:
id=first param=<parameter not set>
id=second param=something
See https://en.cppreference.com/w/cpp/utility/optional
Use default parameters
template <typename T>
void func(T a, T b = T()) {
std::cout << a << b;
}
int main()
{
func(1,4); // a = 1, b = 4
func(1); // a = 1, b = 0
std::string x = "Hello";
std::string y = "World";
func(x,y); // a = "Hello", b ="World"
func(x); // a = "Hello", b = ""
}
Note : The following are ill-formed
template <typename T>
void func(T a = T(), T b )
template <typename T>
void func(T a, T b = a )
With commas separating them, just like parameters without default values.
int func( int x = 0, int y = 0 );
func(); // doesn't pass optional parameters, defaults are used, x = 0 and y = 0
func(1, 2); // provides optional parameters, x = 1 and y = 2
Typically by setting a default value for a parameter:
int func(int a, int b = -1) {
std::cout << "a = " << a;
if (b != -1)
std::cout << ", b = " << b;
std::cout << "\n";
}
int main() {
func(1, 2); // prints "a=1, b=2\n"
func(3); // prints "a=3\n"
return 0;
}
Jus adding to accepted ans of #Pramendra , If you have declaration and definition of function, only in declaration the default param need to be specified