Is there an elegant way to do arithmetic on tuples (like pairs) in C ++?

The name says a lot about everything. I'd like to do:

std::pair<int,int> a(2,1), b(1,1), c(0,0);
c=a-b;

      

and we get c = (1,0). If it has to do with defining a new class and overloading an operator, which I suppose I would still be interested to see the most elegant way to do it, but it would be even better, imo, if it weren't for the accelerated, new class definition. Thank you! -Mark

+3


source to share


3 answers


std :: valarray is designed to support numerical computation on vectors (i.e. ordered orders of numbers).

std::valarray<int> a {2, 1}, b {1, 1}, c;
c = a - b;

      



You can access your elements as if you were accessing those from std::vector

, i.e. using the signature operator []

.

+10


source


You don't need a new class, you can define global templates for free functions like:



template<typename T>
std::pair<T,T> operator - (const std::pair<T,T> & lhs, const std::pair<T,T> & rhs)
{
    return std::pair<T,T>(lhs.first - rhs.first, lhs.second - rhs.second);
}

int main(int argc, char * argv[])
{
    (void)argc; (void)argv;

    std::pair<int,int> a(2,1), b(1,1), c(0,0);
    c=a-b;
    return 0;
}

      

+3


source


You can always write your own operators:

std::pair<int, int> operator+(const std::pair<int, int>& a, 
    const std::pair<int, int>& b)
{
    return std::make_pair(a.first + b.first, a.second + b.second);
}

// other operators here

std::pair<int,int> a(2,1), b(1,1);
auto c = a + b; // yields (3,2)

      

It is even possible to generalize arbitrary tuples with some help from integer sequences (there are plenty of places to look for how to do this):

template <size_t I, typename... T>
typename std::tuple_element<I, std::tuple<T...>>::type
addi(const std::tuple<T...>&a, const std::tuple<T...>&b)
{
    return std::get<I>(a) + std::get<I>(b);
}

template <size_t... I, typename... T>
std::tuple<T...> add(sequence<I...>, const std::tuple<T...>&a, const std::tuple<T...>&b)
{
    return std::make_tuple(addi<I>(a,b)...);
}


template <typename... T>
std::tuple<T...> operator+(const std::tuple<T...>& a, const std::tuple<T...>& b)
{
    return add(typename gen_sequence<sizeof...(T)>::type{}, a, b); 
}


std::tuple<int, int, int> ta{1, 1, 2};
std::tuple<int, int, int> tb{2, 2, 2};

auto tc = ta + tb; // yields <3, 3, 4>

      

+3


source







All Articles