2016-11-23 17 views
7

std::tuple<...>::operator!= कम से कम एक दो तुलनात्मक टुपल्स के सदस्य अलग हैं, तो यह सच है।मैं कैसे जांच सकता हूं कि दो टुपल्स के सभी सदस्य अलग हैं या नहीं?

मैं एक समारोह है कि सच वापसी होगी अगर दो तुलना tuples के सभी सदस्यों अलग हैं की आवश्यकता होगी:

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; 
} 

मैं वेब पर क्या मिला से प्रेरित होकर, मैं इस (एक समारोह अनुकूलित था कि लिखा था टपल सामग्री) मुद्रण:

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; 
} 

लेकिन यह स्पष्ट रूप से सही रूप में संकलक मुझे रिपोर्ट Error C2955 'CheckTupleLoop': use of class template requires template argument list

नहीं है

सी ++ 11 में bool areAllMembersDifferent का कोई भी कार्यान्वयन स्वीकार्य होगा (मेरा पहला प्रयास दृष्टिकोण का उपयोग या नहीं)।

+0

आप दो की सामग्री की जांच करने के लिए इसका मतलब क्या प्राप्त करने के लिए आपको क्या चाहिए निम्नलिखित सी ++ 11 अनुरूप समाधान का उपयोग कर सकते tuples? मैं उलझन में आया * सच हो जाएगा यदि ** ** ** के सभी सदस्य अलग हैं * – Jonas

+0

@ जोनास: जांचें कि क्या दो टुपल्स के सभी सदस्य अलग हैं। पोस्ट संपादित किया गया। – jpo38

+0

बूस्ट। हाना में 'डिसजॉइंट' फ़ंक्शन है जो जांचता है कि टुपल्स में तत्व समान हैं या नहीं। – TemplateRex

उत्तर

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

Demo

के लिए std::make_index_sequence की C++ 11 (जो सी ++ 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) && ...); 
} 

} 
+0

महान काम करता है! धन्यवाद। उम्मीद है कि एक दिन मैं बिना पूछे इस तरह का कोड लिख पाऊंगा .... ;-) – jpo38

2

आप

template <size_t N> 
struct CompareTuples 
{ 
    template<class... Args> 
    static bool areAllMembersDifferent(const std::tuple<Args...>& left, const std::tuple<Args...>& right) 
    { 
     return (std::get<N>(left) != std::get<N>(right)) && CompareTuples<N-1>::areAllMembersDifferent(left, right); 
    } 
}; 

template<> 
struct CompareTuples<0> 
{ 
    template<class... Args> 
    static bool areAllMembersDifferent(const std::tuple<Args...>& left, const std::tuple<Args...>& right) 
    { 
     return (std::get<0>(left) != std::get<0>(right)); 
    } 
}; 

template<class... Args> 
bool areAllMembersDifferent(const std::tuple<Args...>& left, const std::tuple<Args...>& right) 
{ 
    return CompareTuples<std::tuple_size<std::tuple<Args...>>::value-1>::areAllMembersDifferent(left, right); 
} 
0

Jarod42 का जवाब काफी उचित है, लेकिन यहाँ मेरी 2 सेंट है::

#include <iostream> 
#include <tuple> 
#include <limits> 

template <size_t index> 
struct next_index 
{ 
    static const size_t value = index - 1; 
}; 

template <> 
struct next_index<0> 
{ 
    static const size_t value = 0; 
}; 

template <class Tuple, size_t index> 
bool is_same(const Tuple& left, const Tuple& right) 
{ 
    if (index != 0) 
     return is_same<Tuple, next_index<index>::value>(left, right) and std::get<index>(left) != std::get<index>(right); 
    return std::get<index>(left) != std::get<index>(right); 
} 

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

int main() { 
    std::cout << areAllMembersDifferent(std::make_tuple(12, '*', 4.2f), std::make_tuple(11, '#', 4.25f)) << std::endl; 
    std::cout << areAllMembersDifferent(std::make_tuple(12, '*', 4.2f), std::make_tuple(11, '#', 4.2f)) << std::endl; 
} 
संबंधित मुद्दे

 संबंधित मुद्दे