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).
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.
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.
The tuples are checked for being identical using the '==' operator. This is assigned to a value. It is displayed on the console.
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) && ...);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With