Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check if all members of two tuples are different?

std::tuple<...>::operator!= returns true if at least one member of the two compared tuples is different.

I would need a function that would return true if all members of two compared tuples are different:

template <class... Args>
bool areAllMembersDifferent( const std::tuple<Args...>& left, const std::tuple<Args...>& right )
{
    bool allDiff = true;

    // iterate through the tuples are set allDiff to false if one member's is different than other's

    return allDiff;
}

Inspired from what I found on the web, I wrote this (adapted a function that was printing the tuple content):

template <std::size_t N, std::size_t, class = make_index_sequence<N>>
struct CheckTupleLoop;

template <std::size_t N, std::size_t J, std::size_t... Is>
struct CheckTupleLoop<N, J, index_sequence<Is...>> {
    template <class Tup>
    int operator()(bool& allDiff, const Tup &left,const Tup &right) {
        if ( std::get<J>(left) == std::get<J>(right) )
            allDiff = false;
        return 0;
    }
};

template <class... Args>
bool areAllMembersDifferent( const std::tuple<Args...>& left, const std::tuple<Args...>& right )
{
    bool allDiff = true;
    CheckTupleLoop<sizeof...(Args)>{}(allDiff,left,right);
    return allDiff;
}

But this is obviously not correct as the compiler reports me Error C2955 'CheckTupleLoop': use of class template requires template argument list

Any kind of implementation of bool areAllMembersDifferent in C++11 would be acceptable (using or not my first attempt approach).

like image 758
jpo38 Avatar asked Nov 23 '16 10:11

jpo38


People also ask

How do you compare two tuples?

Tuples are compared position by position: the first item of the first tuple is compared to the first item of the second tuple; if they are not equal, this is the result of the comparison, else the second item is considered, then the third and so on.

How do you check if a tuple is in another tuple?

When it is required to check if one tuple is a subset of the other, the 'issubset' method is used. The 'issubset' method returns True if all the elements of the set are present in another set, wherein the other set would be passed as an argument to the method. Otherwise, this method returns False.

How do you check if all items in the tuple are the same?

The tuples are checked for being identical using the '==' operator. This is assigned to a value. It is displayed on the console.


1 Answers

You may use the following:

namespace detail
{

template <std::size_t ... Is, typename Tuple>
bool areAllMembersDifferent(std::index_sequence<Is...>,
                            const Tuple& left,
                            const Tuple& right)
{
    bool res = true;

    const int dummy[] = {0, (res &= std::get<Is>(left) != std::get<Is>(right), 0)...};
    static_cast<void>(dummy); // Avoid warning for unused variable
    return res;
}

}

template <typename Tuple>
bool areAllMembersDifferent(const Tuple&left, const Tuple& right)
{
    return detail::areAllMembersDifferent(
        std::make_index_sequence<std::tuple_size<Tuple>::value>(), left, right);
}

Demo

Implementation for c++11 of std::make_index_sequence (which is C++14) can be found easily

In C++17, you may even simplify the helper function to:

namespace detail
{

template <std::size_t ... Is, typename Tuple>
bool areAllMembersDifferent(std::index_sequence<Is...>,
                            const Tuple& left,
                            const Tuple& right)
{
    return (std::get<Is>(left) != std::get<Is>(right) && ...);
}

}
like image 75
Jarod42 Avatar answered Oct 13 '22 17:10

Jarod42