Achieving clean lambda functions in C++11 - c++

I've been playing around a lot with the new C++11 lambda's, and the requirement to fully specify the template argument is a real drag. The syntax I would like to be using is something similar to the following:
#include <vector>
#include <algorithm>
struct foo
{
void bar() {}
};
int main()
{
vector<foo> v(10);
for_each(v.begin(), v.end(), [](f) {f.bar();});
^^^
}
Is there any way to get anything approximately close to this? Boost's Phoenix library is OK, but the syntax for calling member functions requires lots of boiler plate - I guess I'm after C++11's ease of calling member functions coupled with Phoenix's automatic deduction of type.
Current idea
I have gotten it down to this syntax:
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
Which works, but you have to add the capability per type (eg. ADD_AUTO_LAMBDA_SUPPORT(foo);). It also has the limitation that all supported types can not have any ambiguous members.
The full code for that is:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
struct foo
{
foo() : x(3) {}
int x;
void f() { cout << x << endl;}
};
struct bar
{
bar() : y(133.7) {}
double y;
void b() { cout << y << endl;}
};
struct combo : foo, bar { };
struct _a
{
_a(foo& f) : offset(reinterpret_cast<combo*>(&f)) {}
_a(bar& b) : offset(reinterpret_cast<combo*>((char*)&b - 2*sizeof(foo))) {}
combo* operator->() { return offset; }
private:
combo* offset;
};
int main()
{
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
}
You could then use some template and preprocessor magic to generate both _a and combo, but the issue comes when you have ambiguous names (eg. a third struct with a b() function - you need a way to disambiguate them that I can't think of at the moment.

Note: I fully agree that [](auto f){ ... } would be very desirable!
While we don't have that, what about good old typedef? It just adds one line, is very "low-tech" and makes the lambda easy to read:
typedef const map<key_type, value_type>::value_type& λp_t;
for_each(m.begin(), m.end(), [&](λp_t x) {...});

You can use decltype:
for_each(m.begin(), m.end(), [&](decltype(*m.begin()) x){...});
But it really, really sucks that you cant use auto in anonymous lambdas.
Update:
You could also do
#define _A(CONTAINER_NAME) decltype(*CONTAINER_NAME.begin())
for_each(m.begin(), m.end(), [&](_A(m) x) { ... });

So, presumably in the case of the following:
std::array<int,10> a;
for_each(begin(a),end(a),[](auto i){ /* ... */ });
You want the compiler to figure out that the lambda takes an int and basically read this as:
for_each(begin(a),end(a),[](int i){ /* ... */ });
The issue is that the type of the lambda affects the type of the for_each template instantiation, which might choose a different specialization, which could in turn require a different type deduction for the lambda parameter. So there is simply no reasonable way for the compiler to use the algorithm code to automatically deduce the type of the arguments you pass in.
Anyway, at least for the for_each algorithm you don't need this, just use the range for loop:
for(auto i:a) { /* ... */ }
And in other places use decltype:
transform(begin(a),end(a),begin(a),[](decltype(*begin(a)) i) { return 2*i; });

You can have lambda deduce it parameters(and types) from the function, but then each function has to make that available. This discusses how that could be accomplished here:
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/c347334187628476?hl=en
Basically you can call functions using a ruby-like way. So you would call for_each like this:
$(for_each(some_range), x)
{
printf("%i\n", x);
};
The ($) dollar sign is a macro that takes care of deducing the type from the function. Now this won't work with std::for_each, it has to be used with a specially defined function that emits the parameter types for the lambda.
Since it uses a macro it doesn't take into account operator precedence, so you can't use it with range adapters.

If you're willing to use macros and use all that setup wouldn't a shortcut macro using decltype be sufficient? Something like:
#define T_FOR_EACH( begin_, end_, var_, func_ ) \
for_each( (begin_), (end_), [](decltype(*begin_) var_) func_ )
Then you could have:
T_FOR_EACH(x.begin(), x.end(), &f, {f->f();} );
The reason I don't put & for the variable in the define is that with this format would can still specify all the type specifiers you want and whether it is a reference or copy.
Excuse me if the syntax is wrong, I don't have a C++11 compiler around I can test any of this with, it's just an idea.

So this compiles
#define FOR_EACH_IN(iter__, list__, ...) \
std::for_each(list__.begin(), list__.end(), [&](decltype(*list__.begin()) iter__) __VA_ARGS__)
Given:
auto DoSomethingTo = [](T AnElement){ /* insert profitable activity */ };
std::array<T, n> AnArray;
You can do:
FOR_EACH_IN(AnElement, AnArray,
{
DoSomethingTo(AnElement);
});
The JavaScript fanboy inside me is excited by how it looks but as a C++ coder I'm horrified to have come up with something like this. It's likely to trip lots of static analyses and linters, plus when something goes wrong I hope you enjoy debugging macros.
But, hey, it's clean.

Related

What is the difference between different ways of passing a function as an argument to another function?

I have the situation where one function calls one of several possible functions. This seems like a good place to pass a function as a parameter. In this Quoara answer by Zubkov there are three ways to do this.
int g(int x(int)) { return x(1); }
int g(int (*x)(int)) { return x(1); }
int g(int (&x)(int)) { return x(1); }
...
int f(int n) { return n*2; }
g(f); // all three g's above work the same
When should which method be used? What are there differences? I prefer the simplest approach so why shouldn't the first way always be used?
For my situation, the function is only called once and I'd like to keep it simple. I have it working with pass by pointer and I just call it with g(myFunc) where myFunc is the function that gets called last.
Expanding on L.F.'s comment, it's often better to eschew function pointers entirely, and work in terms of invocable objects (things which define operator()). All of the following allow you to do that:
#include <type_traits>
// (1) unrestricted template parameter, like <algorithm> uses
template<typename Func>
int g(Func x) { return x(1); }
// (2) restricted template parameter to produce possibly better errors
template<
typename Func,
typename=std::enable_if_t<std::is_invocable_r_v<int, Func, int>>
>
int g(Func x) { return std::invoke(x, 1); }
// (3) template-less, trading a reduction in code size for runtime overhead and heap use
int g(std::function<int(int)> x) { return x(1); }
Importantly, all of these can be used on lambda functions with captures, unlike any of your options:
int y = 2;
int ret = g([y](int v) {
return y + v;
});

Generate attribute members into string automatically from C++ class?

I am programming in C++ (still a beginner), and I was wondering a question about generating automatically value members of class into string for example :
class Point
{
private:
int x;
int y;
public:
std::list<std::string> getValues();
}
In my opinion, I think I must code the function getValues, transform the ints into strings and put the string in a list and return the list, but my tutor asks me if there is a way to do this function automatically,without writting the code, and I don't know how to answer.
Because if we add a new member value (ex : int z), we will have to recode the function getValues().Apparently there is some way to do this in Java,but I was wondering if there is similar way into C++.
Best regards
It is difficult to say what your tutor really wanted from you, but if I were your tutor I would love you to learn about Boost.Fusion Adapted Structures and techniques it is based on (in particular typemaps).
Example with Boost.Fusion:
#include <boost/fusion/adapted/struct/define_struct.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/lexical_cast.hpp>
#include <iterator>
#include <list>
#include <string>
#include <iostream>
BOOST_FUSION_DEFINE_STRUCT(
(), Point,
(int, x)
(long, y)
(double, z)
)
template <class Itr> struct collector_t
{
using result_type = Itr;
template <class T>
Itr operator()(Itr itr, T const& val) const { *itr = boost::lexical_cast<std::string>(val); return ++itr; }
};
int main()
{
Point p {123, 456l, 123.456};
// create and populate the resulting list using boost.fusion facilities
std::list<std::string> strings;
auto sink = std::back_inserter(strings);
boost::fusion::fold(p, sink, collector_t<decltype(sink)>());
// dump the resulting list to prove the example
for (auto s: strings) std::cout << s << '\n';
return 0;
}
There is no way to do this automatically in C++. That would require reflection, i.e., code must be able to reason about the fields a class has. This is not possible in C++. It is possible in Java, so you are right, one can do this automatically in Java.
In a non-automated way: using visitation (compile-time).
class Point {
public:
//
// With visitation (names are optional)
//
template <typename Visitor>
void visit(Visitor&& visitor) {
visitor("x", x);
visitor("y", y);
}
template <typename Visitor>
void visit(Visitor&& visitor) const {
visitor("x", x);
visitor("y", y);
}
//
// With tuples
//
auto as_tuple() -> std::tuple<int&, int&> {
return std::tie(x, y);
}
auto as_tuple() const -> std::tuple<int const&, int const&> {
return std::tie(x, y);
}
private:
int x;
int y;
};
Yes, those solutions require some more maintenance. However all the code is exposed without the need to mentally expand a macro. As a result, potential compilation error messages tend to be clearer and understanding is eased.
As for the maintenance burden ?
you can automate (unit-test) the correlation of the two methods (make sure they both return the same number of members in the same order)
automating detection of incomplete methods is slightly harder, but if a member is missing and tested it will show up too
Note: I personally prefer the as_tuple version, it makes writing == and < so easy.
Note: detection of incomplete methods (missing members) can be attempted using sizeof and the ABI rules.
The question really has two parts:
Finding all members and
Converting them to string.
Finding members is not possible in pure C++, because it does not have any form of reflection. You could resort to special declaration macros using the standard preprocessor like Boost.Fusion does or you can use your own preprocessor like OpenC++ or using the Clang front-end.
For converting to strings, the standard approach would then be like this:
template <typename T>
std::string to_string(T const &v) {
std::stringstream s;
s << v;
return s.str();
}
You can avoid typing this in and use Boost.Lexical Cast.
Note that C++11 also has std::to_string, but it is only defined for numeric types and therefore not very useful for this purpose.

C++ : Functors and std::function for a noob

I have a simple problem but I don't know how to solve it because I have never used functors in C++.
I want to do something like that (it is just an example) :
class MyClass
{
void applyFunction(myFunction); /* WRONG SYNTAX */
double *_x;
unsigned int *_size;
};
void MyClass::applyFunction(myFunction) /* WRONG SYNTAX */
{
for (unsigned int i = 0; i < _size; ++i)
myFunction(_x[i], 10.);
}
class OtherClass
{
void myFunction1(double x, double lim);
void myFunction2(double x, double lim);
std::vector _v;
};
void OtherClass::myFunction1(double x, double lim)
{
_v.clear();
if (x > lim)
_v.push_back(x);
}
void OtherClass::myFunction2(double x, double lim)
{
_v.clear();
if (x < lim)
_v.push_back(x);
}
int main()
{
MyClass myClass;
OtherClass otherClass;
myClass.applyFunction(otherClass.myFunction1); /* WRONG SYNTAX */
std::cout<<otherClass._v.size()<<std::endl;
myClass.applyFunction(otherClass.myFunction2); /* WRONG SYNTAX */
std::cout<<otherClass._v.size()<<std::endl;
return 0;
}
What would be the correct syntax to use functors/std::functions ?
Thank you very much !
I'll take you at your word that you want to use functors for this. Just for grins, I'll also assume you want to do this the "right" way, not just find a syntax that will let it compile (and probably run, perhaps doing what you wanted).
In this case, the standard library already has algorithms to support much of what you're doing (especially in C++11). To copy the data that meets some criteria into a target vector, you have std::copy_if (though that's missing in C++98/03 -- you have to reverse the sense of the comparison and use std::remove_copy_if).
Using this, your code becomes something like this:
template <class T>
class less_than {
T limit;
public:
less_than(T lim) : limit(lim) {}
bool operator()(T const &val) { return val < limit; }
};
std::copy_if(source.begin(),
source.end(),
std::back_inserter(target),
less_than<int>(10));
However, if you have C++11 available, it's probably more convenient to use a lambda instead:
std::copy_if(source.begin(),
source.end(),
std::inserter(target),
[](int v) { return v < 10;});
The lambda is basically just a way of getting the compiler to generate an anonymous functor class for you, so there's not much real difference between the two, but the lambda obviously saves quite a bit of typing.
If you're stuck with C++03, you basically just invert the comparison:
template <class T>
class greater_than {
T limit;
public:
bool operator()(T const &val) {
return val > limit;
}
};
std::remove_copy_if(src.begin(),
src.end(),
std::back_inserter(dst),
greater_than(10));
Alternatively, you could write your own copy_if pretty easily -- it was left out of C++98/03 mostly by oversight, not because it needs anything the language doesn't provide, or anything like that (though as I recall, getting all the border conditions exactly right can be a little tricky).
For what it's worth, I should also note that the standard library does have std::less and std::greater, so the less_than and greater_than functors I've given above aren't really necessary. Unfortunately, they just do the comparison, so to use them as we're doing here, you have to use std::bind1st or std::bind2nd to get them to compare to a constant:
std::remove_copy_if(src.begin(),
src.end(),
std::ostream_iterator<int>(std::cout, "\n"),
std::bind1st(std::less<int>(), 10));
void applyFunction(std::function<void(double, double)>);
// ...
applyFunction(std::bind(&OtherClass::myFunction1, &otherClass));

How can it be useful to overload the "function call" operator?

I recently discovered that in C++ you can overload the "function call" operator, in a strange way in which you have to write two pair of parenthesis to do so:
class A {
int n;
public:
void operator ()() const;
};
And then use it this way:
A a;
a();
When is this useful?
This can be used to create "functors", objects that act like functions:
class Multiplier {
public:
Multiplier(int m): multiplier(m) {}
int operator()(int x) { return multiplier * x; }
private:
int multiplier;
};
Multiplier m(5);
cout << m(4) << endl;
The above prints 20. The Wikipedia article linked above gives more substantial examples.
There's little more than a syntactic gain in using operator() until you start using templates. But when using templates you can treat real functions and functors (classes acting as functions) the same way.
class scaled_sine
{
explicit scaled_sine( float _m ) : m(_m) {}
float operator()(float x) const { return sin(m*x); }
float m;
};
template<typename T>
float evaluate_at( float x, const T& fn )
{
return fn(x);
}
evaluate_at( 1.0, cos );
evaluate_at( 1.0, scaled_sine(3.0) );
A algorithm implemented using a template doesn't care whether the thing being called is a function or a functor, it cares about the syntax. Either standard ones (e.g. for_each()) or your own. And functors can have state, and do all kinds of things when they are called. Functions can only have state with a static local variable, or global variables.
If you're making a class that encapsulates a function pointer, this might make the usage more obvious.
The compiler can also inline the functor and the function call. It cannot inline a function pointer, however. This way, using the function call operator can significantly improve performance when it is used for example with the standard C++ libary algorithms.
For example for implementing generators:
// generator
struct Generator {
int c = 0;
virtual int operator()() {
return c++;
}
};
int sum(int n) {
Generator g;
int res = 0;
for( int i = 0; i < n; i++ ) {
res += g();
}
return res;
}
I see potential to yet one exotic use:
Suppose you have object of unknown type and have to declare another variable of same type, like this:
auto c=decltype(a*b)(123);
When such pattern used extensively, decltype become very annoying.
This case can occur when using some smart type system that automatically invent type of result of functions and operators based on types of arguments.
Now, if each specialization of each type of that type system equipped with
magic definition of operator() like this:
template<????> class Num<???>{
//specific implementation here
constexpr auto operator()(auto...p){return Num(p...);}
}
decltype() no more needed, you can write simply:
auto c=(a*b)(123);
Because operator() of object redirects to constructor of its own type.

How to use std::foreach with parameters/modification

I've found myself writing
for(int i=0;i<myvec.size();i++)
myvec[i]->DoWhatever(param);
a lot, and I'd like to compress this into a foreach statement, but I'm not sure how to get param in there without going super-verbose. I've also got things like
for(int i=0;i<myvec.size();i++)
if(myvec[i]->IsOK())
myvec[i]->DoWhatever(param);
and I'd like to rewrite that guy too. Any thoughts?
Oh, also, for various reasons, I don't want to use boost.
#include <vector>
#include <algorithm>
#include <functional>
class X
{
public:
void doWhat(int x) {}
bool IsOK() const {return true;}
};
class CallWhatIfOk
{
public:
CallWhatIfOk(int p): param(p) {}
void operator()(X& x) const
{ if (x.IsOK()) {x.doWhat(param);}}
private:
int param;
};
int main()
{
std::vector<X> myVec;
std::for_each( myVec.begin(),
myVec.end(),
std::bind2nd(std::mem_fun_ref(&X::doWhat),4)
);
std::for_each( myVec.begin(),
myVec.end(),
CallWhatIfOk(4)
);
}
Oh, also, for various reasons, I don't want to use boost.
Valid decision, but most likely the wrong one. Consider Boost as an extension to the STL. C++ is a library-driven language. If you don't take this into account, your code will be qualitatively inferior.
While std::for_each can be used here, the absence of lambda expressions in C++ until C++0x makes this tedious. I advocate using Boost.ForEach! It makes this much easier:
foreach (yourtype x, yourvec)
if (x.IsOK())
x.Whatever();
My preferred solution is usually to write a functor to do what I need:
struct doWhatever {
doWhatever(const Param& p) p(p) {}
void operator(MyVec v&, Param p) {
v.DoWhatever(param);
}
private:
Param p;
};
And then the loop:
std::for_each(myvec.begin(), myvec.end(), doWhatever(param));
Depending on how many variations of this you have, this might be a bit too verbose.
There are plenty of options for doing it inline though.
boost::lambda would let you construct the function you need at the call-site. boost::bind (or the standard library bind functions) would let you bind the parameter param to the function so you don't need to supply it as an argument every time.
boost::lambda is probably the most concise and flexible approach. I usually use the plain functor approach because the syntax is easier to remember. ;)
well when we have compilers that support C++0x lambda expresions, this becomes straightforward and minimally invasive:
std::for_each(myvec.begin(),myvec.end(),[&](X& item){
item->DoWhatever(param);
});
and the second example may look like this:
std::for_each(myvec.begin(),myvec.end(),[&](X& item){
if(item->IsOK())
myvec[i]->DoWhatever(param);
});
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/lambda/if.hpp>
#include <boost/lambda/bind.hpp>
struct A
{
bool IsOK () { return true; }
void DoWhatever (int param) {}
};
struct B
{
bool IsOk (A * a) { return true; }
void DoWhatever (A * a, int param) {}
};
typedef std::vector<A *> Myvec;
void main()
{
Myvec myvec;
int param = 1;
B b;
// first challenge using boost::bind (fnct in the same class)
std::for_each (myvec.begin(), myvec.end(),
boost::bind (&A::DoWhatever, _1, param));
// first challenge using boost::bind (fnct in an external class)
std::for_each (myvec.begin(), myvec.end(),
boost::bind (&B::DoWhatever, &b, _1, param));
// second challange using boost::lambda (fnct in the same class)
std::for_each (myvec.begin(), myvec.end(),
boost::lambda::if_then(
boost::lambda::bind (&A::IsOK, boost::lambda::_1),
boost::lambda::bind (&A::DoWhatever, boost::lambda::_1, param)
)
);
// second challange using boost::lambda (fnct in an external class)
std::for_each (myvec.begin(), myvec.end(),
boost::lambda::if_then(
boost::lambda::bind (&B::IsOK, &b, boost::lambda::_1),
boost::lambda::bind (&B::DoWhatever, &b, boost::lambda::_1, param)
)
);
}
You can simplify it by using namespaces...
If you are using GCC you can define something like:
#define foreach(element, array) \
for(typeof((array).begin()) element = (array).begin(), __end_##element = (array).end();\
element != __end_##element;\
++element)
and use it after like this:
foreach(element, array){
element->DoSomething(); //or (*element)->DoSomething() if type is already a pointer
}
I use this on a custom array but it works fine with std::vector too.