Serving the Quantitative Finance Community

 
User avatar
outrun
Posts: 4573
Joined: January 1st, 1970, 12:00 am

Re: C++11 and C++14 Articles

January 24th, 2018, 1:39 pm

a boolean variable with a runtime value would be a good test.
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

January 24th, 2018, 1:45 pm

Solution 2 which  prefer 
#include <functional>
#include <iostream>

int main()
{

	std::function<double(double)> l1 = [](double x) { return x*x; };
	std::function<double(double)> l2 = [](double x) { return 1.0 / x; };

	bool b = false;
	auto f = b ? l2 : l1;
	std::cout << f(2.0) << '\n'; // 4

	b = true;
	auto f2 = b ? l2 : l1;
	std::cout << f2(2.0) << '\n'; // .5

}
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

January 24th, 2018, 1:54 pm

Solution 3 which is the most maintainable
#include <functional>
#include <iostream>

int main()
{
 std::function<double(double)> fCanonical;

 decltype(fCanonical) l1 = [](double x) { return x*x; };
 decltype(fCanonical) l2 = [](double x) { return 1.0 / x; };

 bool b = false;
 auto f = b ? l2 : l1;
 std::cout << f(2.0) << '\n'; // 4

 b = true;
 auto f2 = b ? l2 : l1;
 std::cout << f2(2.0) << '\n'; // .5

}
 
User avatar
outrun
Posts: 4573
Joined: January 1st, 1970, 12:00 am

Re: C++11 and C++14 Articles

January 24th, 2018, 2:33 pm

It shouldn't compile as each lambda has a unique type even when the signatures are the same (even guaranteed to be unique).

The solution is to use std::function or do type erasure with e.g. boost::variant<decltype(l1), decltype(l2)>> lv; ..or erase with your own way.

test:
auto l1 = [](int x) {return 1;};
auto l2 = [](int x) {return 1;};
static_assert( std::is_same<decltype(l1), decltype(l2)>::value, "l1 has a different type than l2");
 
User avatar
ISayMoo
Posts: 2332
Joined: September 30th, 2015, 8:30 pm

Re: C++11 and C++14 Articles

January 24th, 2018, 3:23 pm

It shouldn't compile as each lambda has a unique type even when the signatures are the same (even guaranteed to be unique).

The solution is to use std::function
Of course, that's the answer. But I do think it's a sad thing to force lambdas to have their own unique type even if they have no captures and the signature is known at compile time. But I suppose it's impossible within C++.
 
User avatar
outrun
Posts: 4573
Joined: January 1st, 1970, 12:00 am

Re: C++11 and C++14 Articles

January 24th, 2018, 3:29 pm

It shouldn't compile as each lambda has a unique type even when the signatures are the same (even guaranteed to be unique).

The solution is to use std::function
Of course, that's the answer. But I do think it's a sad thing to force lambdas to have their own unique type even if they have no captures and the signature is known at compile time. But I suppose it's impossible within C++.
Yes, I agree, or at least make the behaviour selectable either way. Meta programming with a rich type system is a very important part of C++ and unique lambda types aren't very useful in that respect.
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

January 24th, 2018, 4:04 pm

It shouldn't compile as each lambda has a unique type even when the signatures are the same (even guaranteed to be unique).

The solution is to use std::function
Of course, that's the answer. But I do think it's a sad thing to force lambdas to have their own unique type even if they have no captures and the signature is known at compile time. But I suppose it's impossible within C++.
Is that a feature or a bug?

Maybe lambdas were not built for this more heavyweight work. A lambda is just a callable object.

"Defensive programming", std::function is safest (or use a function object).
 
User avatar
outrun
Posts: 4573
Joined: January 1st, 1970, 12:00 am

Re: C++11 and C++14 Articles

January 24th, 2018, 4:25 pm

It shouldn't compile as each lambda has a unique type even when the signatures are the same (even guaranteed to be unique).

The solution is to use std::function
Of course, that's the answer. But I do think it's a sad thing to force lambdas to have their own unique type even if they have no captures and the signature is known at compile time. But I suppose it's impossible within C++.
Is that a feature or a bug?

Maybe lambdas were not built for this more heavyweight work. 
 It's a choice made in the C++ standard, it's what the C++ version of lambdas are defined to be. 
Yes, lambdas are the opposite of reusable & structured but they are handy as e.g. the compare argument in std::sort.
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

January 24th, 2018, 4:32 pm

Lambdas are extremely useful for configuring the application (1-liners). I don't see them as a magic wand to replace templates and functions, but if you want to, go for it.

Not sure if the next generation  of maintenance programmers will be very pleased with autos all over the place.

Some people, like autos, some don't.
 
User avatar
outrun
Posts: 4573
Joined: January 1st, 1970, 12:00 am

Re: C++11 and C++14 Articles

January 24th, 2018, 5:10 pm

Yes indeed, for configuring 1-liners, and not to replace templates or functions
 
User avatar
ISayMoo
Posts: 2332
Joined: September 30th, 2015, 8:30 pm

Re: C++11 and C++14 Articles

January 24th, 2018, 5:47 pm

Some people, like autos, some don't.
PARSE ERROR
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

January 24th, 2018, 5:57 pm

Yes indeed, for configuring 1-liners, and not to replace templates or functions
Yes.
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

January 24th, 2018, 5:58 pm

Some people, like autos, some don't.
PARSE ERROR
I'll get @tags onto this. 
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

January 24th, 2018, 11:58 pm

Lambda functions have this annoying feature that this does not work:

auto l1 = [](double x) { return x*x; };
auto l2 = [](double x) { return 1.0 / x; };

auto l = use_l2 ? l2 : l1;

At least in VS 2015. Why can't two lambdas of the same signature be treated as instances of the same type???
In a function declaration that uses the trailing return type syntax, the keyword auto does not perform automatic type detection. It only serves as a part of the syntax.

More C++ for lawyers here

http://en.cppreference.com/w/cpp/language/auto

edit: my take is stored lambda functions like l1 and l2 are mapped to anonymous function objects by the compiler. 
Also, saying a variable is auto but in  the case of a function it is not clear. Maybe better to be explicit and remove all doubt?
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

July 27th, 2018, 6:19 pm