Home > Backend Development > C++ > Can Tuples Work with Unordered Containers Without Variadic Templates in C 0x?

Can Tuples Work with Unordered Containers Without Variadic Templates in C 0x?

Susan Sarandon
Release: 2024-11-12 01:16:03
Original
972 people have browsed it

Can Tuples Work with Unordered Containers Without Variadic Templates in C  0x?

Making C 0x Tuples Work with Unordered Containers

While creating unordered maps and sets using tuple keys should be straightforward, requiring a custom hash function for tuples can be tedious. But is there a way to avoid this without using variadic templates?

The Standard Solution

In C 0x, a generic hash function for tuples can be defined using the code below:

namespace std{
    namespace
    {
        // Code from boost
        // Reciprocal of the golden ratio helps spread entropy
        //     and handles duplicates.
        // See Mike Seymour in magic-numbers-in-boosthash-combine:
        //     http://stackoverflow.com/questions/4948780

        template <class T>
        inline void hash_combine(std::size_t&amp; seed, T const&amp; v)
        {
            seed ^= std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
        }

        // Recursive template code derived from Matthieu M.
        template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
        struct HashValueImpl
        {
          static void apply(size_t&amp; seed, Tuple const&amp; tuple)
          {
            HashValueImpl<Tuple, Index-1>::apply(seed, tuple);
            hash_combine(seed, std::get<Index>(tuple));
          }
        };

        template <class Tuple>
        struct HashValueImpl<Tuple,0>
        {
          static void apply(size_t&amp; seed, Tuple const&amp; tuple)
          {
            hash_combine(seed, std::get<0>(tuple));
          }
        };
    }

    template <typename ... TT>
    struct hash<std::tuple<TT...>> 
    {
        size_t
        operator()(std::tuple<TT...>&amp; tt) const
        {                                              
            size_t seed = 0;                             
            HashValueImpl<std::tuple<TT...>>::apply(seed, tt);    
            return seed;                                 
        }                                              
    };
}
Copy after login

Using a Custom Namespace

To ensure compliance with the standard, it's recommended to define the hash function for tuples in a custom namespace, preventing it from being automatically picked up by ADL. This requires declaring the hash implementation in the custom namespace first, followed by including the rest of the generic hash function code:

namespace hash_tuple{

template <typename TT>
struct hash
{
    size_t
    operator()(TT const&amp; tt) const
    {                                              
        return std::hash<TT>()(tt);                                 
    }                                              
};
}

// ... Include the rest of the previous generic hash function code
Copy after login

This way, unordered maps and sets can work with tuple keys without relying on ADL, and the standard is fully adhered to.

The above is the detailed content of Can Tuples Work with Unordered Containers Without Variadic Templates in C 0x?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template