简体   繁体   中英

Re-defining std::hash template struct

Normally, if a hash is needed for a new type, std::hash must be specialized. I wrote a test hashing library and would like to use it for all types not already specialized by the standard library.

I tried the following with gcc/4.9.3 and clang/3.7.0. To my surprise, it works.

#include <utility>
#include <functional>
#include <iostream>

namespace std {

template<typename T>
class hash
{
    public:
        size_t operator()(const T & obj)
        {
            return 99;
        }
};
}

int main(void)
{
    int i = 10;
    std::pair<int, int> pi{22,33};

    std::hash<int> hi;
    std::hash<std::pair<int, int>> hpi;

    std::cout << "Hash of int: " << hi(i) << "\n";
    std::cout << "Hash of int pair: " << hpi(pi) << "\n";
    return 0;
}

The hash of the integer is the integer itself (which is the standard library version) and the hash of the pair is 99.

So two questions.

  1. Why does it work? the templated version of std::hash should already be declared. (My only guess is it's in a deeper namespace, which gets forwarded)

  2. Is this standard behavior?

Edit: Answer to question 1 - template<typename T> struct hash is declared, but doesn't seem to be defined anywhere. That is why I can define it.

17.6.4.2.1 Namespace std [namespace.std]

1 The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

Since you redefined a general template that already exists to namespace std , you have undefined behavior. And that includes as @TC mentions in the comments, that the program works fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM