1

I found in this question this implementation for a generic hash for tuple to use in an unordered_map.

Here is the code that I copied and pasted in the linked question saved in VariadicTuple.cpp:

#include <tuple>

//code taken from https://stackoverflow.com/questions/7110301/generic-hash-for-tuples-in-unordered-map-unordered-set

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:
        //     https://stackoverflow.com/questions/4948780

        template <class T>
        inline void hash_combine(std::size_t& seed, T const& 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& seed, Tuple const& 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& seed, Tuple const& tuple)
            {
                hash_combine(seed, std::get<0>(tuple));
            }
        };
    }

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

    };
}

It compile on C++ shell (demo here) but on MSVC 14 it returns this error:

1>------ Build started: Project: CloudCache, Configuration: Debug Win32 ------
1>  VariadicTuple.cpp
1>  Utility.cpp
1>  Memoization.cpp
1>  HelloWorld.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\xstddef(381): error C2338: The C++ Standard doesn't provide a hash for this type.
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\variadictuple.cpp(18): note: see reference to class template instantiation 'std::hash<T>' being compiled
1>          with
1>          [
1>              T=std::vector<double,std::allocator<double>>
1>          ]
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\variadictuple.cpp(37): note: see reference to function template instantiation 'void std::`anonymous-namespace'::hash_combine<std::vector<double,std::allocator<_Ty>>>(size_t &,const T &)' being compiled
1>          with
1>          [
1>              _Ty=double,
1>              T=std::vector<double,std::allocator<double>>
1>          ]
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\variadictuple.cpp(36): note: while compiling class template member function 'void std::`anonymous-namespace'::HashValueImpl<std::tuple<_Ty>,0>::apply(size_t &,const Tuple &)'
1>          with
1>          [
1>              _Ty=vecD,
1>              Tuple=std::tuple<vecD>
1>          ]
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\variadictuple.cpp(49): note: see reference to function template instantiation 'void std::`anonymous-namespace'::HashValueImpl<std::tuple<_Ty>,0>::apply(size_t &,const Tuple &)' being compiled
1>          with
1>          [
1>              _Ty=vecD,
1>              Tuple=std::tuple<vecD>
1>          ]
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\variadictuple.cpp(49): note: see reference to class template instantiation 'std::`anonymous-namespace'::HashValueImpl<std::tuple<_Ty>,0>' being compiled
1>          with
1>          [
1>              _Ty=vecD
1>          ]
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\variadictuple.cpp(47): note: while compiling class template member function 'size_t std::hash<_Kty>::operator ()(const std::tuple<_Ty> &) const'
1>          with
1>          [
1>              _Kty=noRef,
1>              _Ty=vecD
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xhash(114): note: see reference to function template instantiation 'size_t std::hash<_Kty>::operator ()(const std::tuple<_Ty> &) const' being compiled
1>          with
1>          [
1>              _Kty=noRef,
1>              _Ty=vecD
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(522): note: see reference to class template instantiation 'std::hash<_Kty>' being compiled
1>          with
1>          [
1>              _Kty=noRef
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(264): note: see reference to class template instantiation 'std::is_empty<_Ty1>' being compiled
1>          with
1>          [
1>              _Ty1=std::hash<noRef>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\unordered_map(23): note: see reference to class template instantiation 'std::_Uhash_compare<_Kty,_Hasher,_Keyeq>' being compiled
1>          with
1>          [
1>              _Kty=noRef,
1>              _Hasher=std::hash<noRef>,
1>              _Keyeq=std::equal_to<noRef>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xhash(152): note: see reference to class template instantiation 'std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>' being compiled
1>          with
1>          [
1>              _Kty=noRef,
1>              _Ty=vecD,
1>              _Hasher=std::hash<noRef>,
1>              _Keyeq=std::equal_to<noRef>,
1>              _Alloc=std::allocator<std::pair<const noRef,vecD>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\unordered_map(86): note: see reference to class template instantiation 'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>' being compiled
1>          with
1>          [
1>              _Kty=noRef,
1>              _Ty=vecD,
1>              _Hasher=std::hash<noRef>,
1>              _Keyeq=std::equal_to<noRef>,
1>              _Alloc=std::allocator<std::pair<const noRef,vecD>>
1>          ]
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\memoization.cpp(28): note: see reference to class template instantiation 'std::unordered_map<noRef,ReturnType,std::hash<_Kty>,std::equal_to<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' being compiled
1>          with
1>          [
1>              ReturnType=vecD,
1>              _Kty=noRef,
1>              _Ty=vecD
1>          ]
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\memoization.cpp(46): note: see reference to function template instantiation 'std::function<vecD (vecD &)> memoize<vecD,vecD&>(const std::function<vecD (vecD &)> &)' being compiled
1>  c:\users\llovagnini\source\repos\cloudcache\cloudcache\cloudcache\helloworld.cpp(38): note: see reference to function template instantiation 'void MultiMemoizator::addFunction<vecD,vecD&>(const MemFunc<vecD (vecD &)> &)' being compiled
1>  Exceptions.cpp
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Why this happens?

Community
  • 1
  • 1
justHelloWorld
  • 6,478
  • 8
  • 58
  • 138
  • Don't post links to code, but post the minimum code that produces the problem. – Jabberwocky Apr 29 '16 at 08:53
  • @MichaelWalz updated with code – justHelloWorld Apr 29 '16 at 08:55
  • The code you used in the C++ shell is not relevant. You never use any of the templates, thus no code is generated from the templates. Try to include objects derived from your templates in the main to get a relevant result. – Paul R. Apr 29 '16 at 09:51
  • Here's the C-Shell code with 2 instantiations, one (`#ifdef 0` at the moment) with `tuple` (the example mentioned by the original coder), and the other with `tuple >` (which you tried to compile with MSVC). Running the first example works well, but the vector tuple barfs as much as MSVC. http://cpp.sh/9apt – Christopher Oicles Apr 29 '16 at 09:59

0 Answers0