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

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.

Related

Boost: Store Pointers to Distributions in Vector

Hi Stack Exchange Experts,
I'm trying to collect pointers to different statistical distributions provided by Boost in one vector.
If distributions would be derived from one (virtual) parent class I could write something like
std::vector<Parent> v;
boost::math::normal_distribution<double> n;
boost::math::students_t_distribution<float> t(4);
boost::math::normal_distribution<double> *p1 = new boost::math::normal_distribution<double>(n);
boost::math::students_t_distribution<float> *p2 = new boost::math::students_t_distribution<float>(t);
v.push_back(p1);
v.push_back(p2);
and then iterate over the vector and apply functions etc. to the dereferenced pointers.
But since this is not the case I don't really know how to store the pointers in one place?
So my question is, if there is a way to store pointers to different template classes in one variable/list/vector... (that can be handled conveniently like std::vector for example).
Remark that for example the Boost pdf density function can be applied to the dereferenced pointers regardless of the specific type (so storing them in one vector makes sense in some cases).
//////////////////////////////////////////////////////////////////////////
I played around with the different (nice) answers and finally decided to stick to boost::variant in conjunction with boost::static_visitor.
Below is a full application that does what I outlined in my original question:
#include <boost/math/distributions.hpp>
#include <boost/variant.hpp>
#include <vector>
#include <iostream>
//template based visitor to invoke the cdf function on the distribution
class cdf_visitor_generic : public boost::static_visitor<double>
{
public:
//constructor to handle input arguments
cdf_visitor_generic(const double &x) : _x(x) {}
template <typename T>
double operator()(T &operand) const {
return(boost::math::cdf(operand,_x));
}
private:
double _x;
};
//shorten typing
typedef boost::variant< boost::math::normal_distribution<double>, boost::math::students_t_distribution<double> > Distribution;
int main (int, char*[])
{
//example distributions
boost::math::normal_distribution<double> s;
boost::math::students_t_distribution<double> t(1);
//build a variant
Distribution v = t;
//example value for evaluation
double x = 1.96;
//evaluation at one point
double y = boost::apply_visitor( cdf_visitor_generic(x),v);
std::cout << y << std::endl;
//build a vector and apply to all elements of it:
std::vector<Distribution> vec_v;
vec_v.push_back(s);
vec_v.push_back(t);
for (std::vector<Distribution>::const_iterator iter = vec_v.begin(); iter != vec_v.end(); ++iter){
//apply cdf to dereferenced iterator
double test = boost::apply_visitor( cdf_visitor_generic(x), *iter);
std::cout << test << std::endl;
}
return 0;
}
The only drawback I see is that the type of distribution needs to be explicitly specified (in the variant) so it could be that boost::any adds more freedom.
Thank you for the great help!
Hank
You can use a variant:
std::vector<boost::variant<
boost::math::normal_distribution<double>,
boost::math::students_t_distribution<float>
> > v;
boost::math::normal_distribution<double> n;
boost::math::students_t_distribution<float> t(4);
v.push_back(n);
v.push_back(t);
I have several answers that show how to use these elements "polymorphically" (though the polymorphism is by statically compile typeswitching, instead of vtable dispatch). I'll add a link or two soon.
Generating an interface without virtual functions?
Avoid RTTI when dealing with pairs of objects
More involved: boost::mpl::fold for double parameter abstraction
Some of the linked answers show the "manual" approach to type erasure
PS. I should probably mention boost::any too, but I dislike it for several reasons. I shan't recommend it for this purpose.
You can't store pointers to unrelated types in single vector. One way to achieve this would be to make a vector of void*:
std::vector<void*>
But I would strongly discourage you from doing this as this is not much of a c++ way.
Better solution would be to create custom class hierarchy for storing different kinds of pointers, for example:
class DistributionBase {
public:
virtual ~DistributionBase() {}
}
template<typename T>
class Distribution : public DistributionBase {
public:
typedef T DistributionType;
T* distribution;
Distribution(T* d) : distribution(d) {}
~Distribution() { delete distribution; }
}
template<typename T>
Distribution<T>* make_distribution(T* d) {
return new Distribution<T>(d);
}
And then you can use it as follows:
std::vector<DistributionBase*> distributions;
distributions.push_back(make_distribution(new boost::math::normal_distribution<double>(n)))
distributions.push_back(make_distribution(new boost::math::students_t_distribution<float>(n)))
The problem is, that you have to store the type of distribution somewhere so you can static_cast to correct type:
boost::math::normal_distribution<double>* d = static_cast< Distribution<boost::math::normal_distribution<double> > >(distributions[0])->distribution;
This is just a snippet that should show you the point not a complete example.
You can wrap pointers around your common base class. Here I will use Template Method Pattern:
class Distribution {
public:
double pdf( double d) { doPdf( d)};
private:
virtual double doPdf( double d) {} = 0;
virtual ~Distribution() {}
};
class NormalDistribution : public Distribution {
private:
boost::math::normal_distribution<double> nd;
double doPdf( double d) { return pdf( nd, d);}
};
class StudentsTDistribution : public Distribution {
private:
boost::math::students_t_distribution<double> std;
double doPdf( double d) { return pdf( std, d);}
};
usage:
std::vector< boost::shared_ptr<Distribution> > v;
v.push_back( boost::make_shared<NormalDistribution>());
v.push_back( boost::make_shared<StudentsTDistribution>());
v[0]->pdf( 0.5); // draw from Gauss's distribution
v[1]->pdf( 0.5); // draw from fatter tails - t Student distribution

Most cpu-efficient way to use std:: algorithms with arguments to a variadic function template?

Say you have a variadic function template which takes a functor and a sequence of homogeneous types, and you want to use std::accumulate to fold the sequence, like so:
template<typename BinaryFuncType, typename... ArgTypes>
do_something(const BinaryFuncType& f, const ArgTypes&... objects)
{
// ...
// use std::accumulate to fold 'objects' using 'f'
// ...
}
Is it possible to pass the variadic arguments (objects) to the range algorithm (std::accumulate) directly, i.e., without incurring the costs of copying the objects (or references) to an iterable container?
You can create a container of std::reference_wrapper objects and accumulate over that. Here's an example:
#include <iostream>
#include <functional>
#include <algorithm>
#include <array>
using namespace std;
template<typename... ArgTypes>
int sum(const ArgTypes&... numbers) {
array<reference_wrapper<const int>, sizeof...(numbers)> A = {ref(numbers)...};
return accumulate(A.begin(), A.end(), 0);
}
int main() {
int x = 1, y = 2, z = 3;
cout << sum(x, y, z) << endl; // prints 6
}
I'll leave it to you to figure out how to adapt this to a more general setting like in your question.
Apparently yes but in a twisted way. Consider the following code:
#include <algorithm>
#include <array>
#include <cstdio>
#include <iterator>
template<typename... Ts>
int sum(Ts... numbers) {
std::array<int,sizeof...(numbers)> list{{numbers...}};
return std::accumulate(std::begin(list), std::end(list), 0);
}
__attribute__((noinline))
void f(int x, int y, int z) {
std::printf("sum = %d\n", sum(x, y, z));
}
int main(int argc, char* argv[]) {
int x = std::atoi(argv[1]);
int y = std::atoi(argv[2]);
int z = std::atoi(argv[3]);
f(x, y, z);
}
I looked at the generated assembly code. Here is what sum() is optimized into by clang, the assembly code rewritten to C by me for clarity:
int sum(int x, int y, int z) {
int tmp = x;
tmp += y;
tmp += z;
return tmp;
}
I can say that the generated assembly code is optimal! It got rid of the temporary std::array and unrolled the loop in std::accumulate().
So the answer to your question: even if you create a temporary iterable container, it can be optimized away if the compiler is smart enough and your numeric types are simple enough (built-in types or PODs). You won't pay for the creation of a temporary container or for copying the elements into the temporary container if it can be optimized away.
Sadly, gcc 4.7.2 wasn't that dexterous:
int sum(int x, int y, int z) {
int a[3];
a[0] = x;
a[1] = y;
a[2] = z;
int tmp = x;
tmp += y;
tmp += z;
return tmp;
}
Unfortunately, it did not recognize that it can get rid of the temporary array. I will check that with the latest gcc from trunk and if the problem still exists, file a bug report; it seems like a bug in the optimizer.
Once your template is instanciated, the compiler sees a number of distinct parameters. Each argument can even be of a different type.
It's exactly as if you wanted to iterate over the arguments of fun (a, b, c, d) and expect the code optimizer to cope with layers upon layers of obfuscation.
You could go for a recursive template, but that would be as cryptic as inefficient.
You could design a template-less variadic function, but then you would have to use the <cstdarg> interface and could kiss std::accumulate goodbye.
Possibly you could use the variadic arguments as an initializer for a plain old array and use std::accumulate on it, provided you restrict the use of your shiny new toy to possibly inlineable parameters, namely a list of objects that can be converted to a single base type at compile time.
If you have big and costly objects, this method can still be used with const references to the said objects. I suppose you will spend quite a bit of time optimizing the operators involved in the accumulation computation if you want to squeeze performances out of it, but well, anything is doable with enough blood and sweat.
#include <array>
#include <numeric>
#include <type_traits>
using namespace std;
// Since we need to get back the base type, might as well check that the
// "optimized" code is not fed with junk that would require countless implicit
// conversions and prevent the compiler from inlining the stupid dummy function
// that should just act as a wrapper for the underlying array initialization.
template<class T, class...>
struct same_type
{
static const bool value = true;
typedef T type;
};
template<class Ta, class Tb, class... Types>
struct same_type<Ta, Tb, Types...>
{
static const bool value = is_same<Ta,Tb>::value && same_type<Tb, Types...>::value;
typedef Ta type;
};
// --------------------------------------------------------
// dummy function just here to make a copy of its arguments
// and pass it to std::accumulate
// --------------------------------------------------------
template<typename F, typename...Args>
typename same_type<Args...>::type do_something(F fun, Args...args)
{
// just a slight bit less of obfuscation
using base_type = same_type<Args...>::type;
// make sure all arguments have the same type
static_assert(same_type<Args...>::value, "all do_something arguments must have the same type");
// arguments as array
array<base_type, sizeof...(Args)> values = { args... };
return accumulate (values.begin(), values.end(), (base_type)0, fun);
}
// --------------------------------------------------------
// yet another glorious functor
// --------------------------------------------------------
struct accumulator {
template<class T>
T operator() (T res, T val)
{
return res + val;
}
};
// --------------------------------------------------------
// C++11 in its full glory
// --------------------------------------------------------
int main(void)
{
int some_junk = do_something(accumulator(),1,2,3,4,6,6,7,8,9,10,11,12,13,14,15,16);
double more_junk = do_something(accumulator(),1.0,2.0,3.0,4.0,6.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0);
return some_junk+(int)more_junk;
}
I had a look at the muck generated by the latest Microsoft compiler.
It did inline the double version entirely. Most of the code is busy initializing the array, the rest is a half-dozen instructions loop. Note that the loop was not unrolled either.
It did not inline the int version completely. It removed the dummy function call but generated an instance of the accumulate template.
Not surprisingly, the compiler won't bother to optimize a function if it reckons the number and size of parameters passed don't justify it, since it has no way to know this piece of code will be called a few gazillion times per second by an idiotic design.
You could certainly have a lot of fun sprinkling the code with register and inline directives and pragmas and tweaking the compiler optimization options, but it's a dead end, IMHO.
A perfect example of bad design using supposedly cutting edge technology to bonk rocks together, if you ask me.

Designing a high perfomance numeric function in c++

I am building on a numeric C++ library that aims in achieving high performance computations (off course double-types will be the main arithmetic type). Therefore i am making heavy use of template metaprogramming. Describing what i want to build and when my "problem" occurs can be cumbersome to read so i have created a toy example that "simulates" to what i want to do.
Consider that i want to design a method that it takes a container, scales its contents against some constants and returns the sum of the scaled numbers. For simplicity, lets assume that i want it to work on containers of size 3. The constants can vary so when programming, the programmer(user of the lib) will have to supply them. The problem is that these constants can be single or double precision, something that can be used as template arguments.
Though, on the other hand, i would like the compiler to emmit code that will be as if i have hard-coded the constants.
Consider the following code:
#include <iostream>
#include <vector>
#include <boost/array.hpp>
using namespace std;
template<class T, class Coefs>
struct scale_add{
Coefs coefs;
template <class Iterator>
T apply(Iterator it){
return coefs[0] * (*(it)) + coefs[1] * (*(it + 1)) + coefs[2] * (*(it + 2));
}
};
template <class T>
struct my_coefs : public boost::array<T, 3>{
my_coefs() {
(*this)[0] = static_cast<T>(3.0);
(*this)[1] = static_cast<T>(2.7);
(*this)[2] = static_cast<T>(4.78);
}
};
int main(){
vector<double> my_vec(3, 9.1) ;
typedef scale_add<double, my_coefs<double> > my_scale_add;
my_scale_add msa;
double result = msa.apply(my_vec.begin() );
cout << result << endl;
return 0;
}
As you see, the programmer will be able to make types like my_scale_add ! This is the design solution i have for the moment. I have tried to express the "floats" as structs with a function value() that will return the number :
struct a1{
typedef double type;
static double value(){
return 0.5;
}
};
This way i put my types into typelist etc. The only problem with this is that it can get confusing and it is possible to face type redefinitions etc. But when i write something like
cout << a1::value() * 4.0 << endl;
the compiler will inline it (according to some references i have).
So my question is, how can i get the behavior of the second way (a1::value() ), without having a huge programming overhead with type packing into typelists etc ? Can you propose a more efficient way to express the first code (ok, this can be considered a bad question) ? Concluding, i want to say that i am not sure if the question fits the stackoverflow, and, i am new to C++ and had to jump from what is a header file to what is template metaprogramming so i might have overlooked some information in the middle, meaning that it is possible that i am asking something trivial. Thank you in advance !
Though I don't completely understand what you mean, I think the following codes may fit your requirement.
template<typename Container>
struct scale_add
{
typedef typename Container::traits_type type;
Container Impl ;
template<typename Iterator>
type apply( Iterator First ) {
return std::inner_product( std::begin(Impl) , std::end(Impl) ,
First , type(0) );
}
};
template<typename K>
struct my_scale_add : public std::array<K , 3>
{
typedef K traits_type ;
my_scale_add() {
(*this)[0] = static_cast<K>( 1.0 );
(*this)[1] = static_cast<K>( 2.0 );
(*this)[2] = static_cast<K>( 3.0 );
}
};
int main()
{
std::vector<double> my_vec(3,9.1);
scale_add<my_scale_add<double>> mObject ;
std::cout << mObject.apply( std::begin(my_vec) ) << std::endl;
return 0;
}

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));

Achieving clean lambda functions in C++11

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.