Вопрос

Why doesn't the C++ standard specify that std::hash<T> is specialized for char*, const char*, unsigned char*, const unsigned char*, etc? I.e., it would hash the contents of the C string until the terminating null is found.

Any harm in injecting my own specializations into the std namespace for my own code?

Это было полезно?

Решение

Why doesn't the C++ standard specify that std::hash<T> is specialized for char*, const char*, unsigned char*, const unsigned char*, etc?

It looks like it originated from proposal N1456. (emphasis mine)

Some earlier hash table implementations gave char* special treatment: it specialized the default hash function to look at character array being pointed to, rather than the pointer itself. This proposal removes that special treatment. Special treatment makes it slightly easier to use hash tables for C string, but at the cost of removing uniformity and making it harder to write generic code. Since naive users would generally be expected to use std::basic_string instead of C strings, the cost of special treatment outweighs the benefit.

If I'm interpreting this correctly, the reasoning is that supporting C style strings would break code that generically acts on hashes of pointers.

Any harm in injecting my own specializations into the std namespace for my own code?

There is potential harm, yes.

  • In the future, anything you added to the std namespace could collide with a new symbol name.
  • In the present, anything you add to the std namespace could be a "better match" for other components of the standard library, silently breaking behavior.

Другие советы

char* (and its ilk) doesn't always mean string. They can be simple byte arrays or binary file dumps or any number of other things. If you mean string in C++, you generally use the "string" class.

As for creating your own, given the above it's a bad idea. For user defined types, though, it is acceptable to create specializations of the std:: functions in the std:: namespace.

There is a standard specialization for pointer types, see here

template< class T > struct hash<T*>;

So, it can cover char* (as sequence of bytes not a C-style string) too.

If you mean a specialization for C-style strings, there's not technically a problem to implement that. But since there is a specialization for std::string in C++, it's not worth to have a specialization for C-style strings.

For second part of your question, you can inject everything in std namespace but, what do you gain? It's against the goal of namespaces. Have your own namespace territory.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top