
On 02/10/2012 07:21 PM, Bill Buklis wrote:
On 2/10/2012 2:50 AM, Philipp Moeller wrote:
Bill Buklis
writes: Is there any facility to perform arithmetic operations on a tuple?
For example:
struct data { double a, b; };
data d1 = {1.0, 2.0}; data d2 = {2.5, 5.5};
// These two lines are not valid, but simulate what I want. boost::tie(d1.a, d1.b) *= 10.0; // Multiply each element by 10.0 boost::tie(d1.a, d1.b) += boost::tie(d2.a, d2.b); // Add the elements from the second object
After calculations, d1 should equal {12.5, 25.5}; Using a tuple this way is probably not the best idea. Tuples are intended for heterogeneous types. If all you really want is a fixed length container for doubles you should use boost/std::array<double>.
If you really insist on the tuple, here is
tuple_for_each isn't that hard:
template
inline void for_each(boost::tuples::cons const& tuple, F f) { f(tuple.get_head()); } template
inline void for_each(boost::tuples::cons const& tuple, F f) { f(tuple.get_head()); for_each(tuple.get_tail(), f); } double a, b; for_each(tie(a,b), [](double& x) { x *= 10.0; })
HTH, Philipp Moeller
Thanks. That looks interesting. In my example I only used doubles, but I was thinking in the more general sense where the types may be different as long as they were compatible with the operand. The second example could easily have different types, since it only matters that a1 is compatible with a2, b1 is compatible with b2, and so on.
In my specific case that made me think of this, I had a structure with several elements in it. An array was unsuitable and unnecessary. I was just wondering if there was something similar to the comparison operators for tuple rather than having to add extra operators for the structure. For this case I just went ahead and added them.
I guess it seemed logical that tuple could have arithmetic operators (at least for example 2) that act just like the comparison operators that operate on each like element in turn. From your example it looks like it would be fairly easy to write one. I don't know what the pros and cons would be for having that in the library.
As Jeffrey already noted, this is where fusion + phoenix really starts to shine. Especially if you have a tuple with different data types, you won't get far with C++11 lambdas. Using fusion::for_each, fusion::transform with an appropriate phoenix expression might do the trick here. Note that tuples are a very generic datatype, it wouldn't make a lot of sense to add some special operators to them. If you think in a functional programming kind of, phoenix is the answer.