Search code examples
c++stltuplestr1template-meta-programming

C++ Find element in list of tuples using predicate


I have a stl::list of tuples which I want to search for element using std::find_if using multiple type comparison in each. Can I associate a tuple type with a specific templated get() function? So there will be no need to pass field number to a predicate template.

I created a predicate like this:

template<typename T, size_t field>
struct obj_predicate : public std::unary_function<ObjectRecordType, bool>
{
    const T* comparisonObject;
    obj_predicate(const T& cObj) : comparisonObject(&cObj) {}
    bool operator()(const ObjectRecordType& obj) const
    {
        return *comparisonObject == std::tr1::get<field>(obj);
    }
};

What I want is like obj_predicate<int>(3) aware of a position of int in tuple.


Solution

  • We could use a "loop". This will return the last index matching the element with the given type.

    template <typename T, typename S, int i = std::tr1::tuple_size<T>::value - 1>
    struct tuple_index
    {
        enum
        {
            value = std::tr1::is_same<typename std::tr1::tuple_element<i, T>::type, S>::value ?
                i :
                tuple_index<T, S, i-1>::value
        };
    };
    
    template <typename T, typename S>
    struct tuple_index<T, S, -1>
    {
        enum { value = -1 };
    };
    

    Example:

    printf("%d\n", tuple_index<std::tr1::tuple<int, double>, int>::value);    // 0
    printf("%d\n", tuple_index<std::tr1::tuple<int, double>, double>::value); // 1
    printf("%d\n", tuple_index<std::tr1::tuple<int, double>, long>::value);   // -1