如何检查两个元组的所有成员是否不同?

jpo*_*o38 7 c++ tuples c++11 stdtuple

std::tuple<...>::operator!=如果两个比较元组中至少有一个成员不同,则返回true .

如果两个比较元组的所有成员不同,我需要一个返回true的函数:

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;
}
Run Code Online (Sandbox Code Playgroud)

受到我在网络上发现的启发,我写了这个(改编了一个打印元组内容的函数):

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;
}
Run Code Online (Sandbox Code Playgroud)

但这显然不正确,因为编译器报告我 Error C2955 'CheckTupleLoop': use of class template requires template argument list

bool areAllMembersDifferent在C++ 11中的任何类型的实现都是可以接受的(使用或不使用我的第一次尝试方法).

Jar*_*d42 5

您可以使用以下内容:

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);
}
Run Code Online (Sandbox Code Playgroud)

演示

std::make_index_sequence可以很容易地找到c ++ 11 (即C++ 14)的实现

在C++ 17中,您甚至可以将辅助函数简化为:

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) && ...);
}

}
Run Code Online (Sandbox Code Playgroud)