Boost logo

Boost Users :

Subject: Re: [Boost-users] [tuple] Tuple arithmetic
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2012-02-11 05:20:38


On 02/10/2012 07:21 PM, Bill Buklis wrote:
> On 2/10/2012 2:50 AM, Philipp Moeller wrote:
>> Bill Buklis<boostusr_at_[hidden]> 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<class T, class F>
>> inline void for_each(boost::tuples::cons<T, boost::tuples::null_type>
>> const& tuple, F f)
>> {
>> f(tuple.get_head());
>> }
>>
>> template<class T, class U, class F>
>> inline void for_each(boost::tuples::cons<T, U> 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.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net