Topic: Make standard string hashes available to custom classes


Author: Miro Knejp <miro@knejp.de>
Date: Mon, 2 Dec 2013 18:47:20 -0800 (PST)
Raw View
------=_Part_5072_31038154.1386038840927
Content-Type: text/plain; charset=ISO-8859-1

Greetings,

it occurred to me the current setup of std::hash is not very open to
extension for foreign string classes. Trying to hash a string coming for
example from a third party library the only way to have them achieve the
same hash values as std::hash<std::string> is by taking a detour using a
std::string temporary.

A motivational example:
template<>
struct std::hash<MyFancyString>
{
    size_t operator() (const MyFancyString& s) { return hash<string>{}(
string(s)); }
};
It is also the only way to hash a string coming from a C interface, since
std::hash<char*> hashes the pointer value, not the string pointed to.

This assumes there is a hypothetical conversion from MyFancyString to
std::string available. This is obviously quite an inefficient solution but
the only one I am aware of to hash any sequence of characters using the
same implementation as the standard hash. One could of course roll out a
custom hash implementation and use it consistently but why reinvent the
wheel when there already is a hash algorithm for strings in the standard?
(unless for very special use cases)

My idea is to move the actual hashing into freestanding functions, exposing
the algorithms used by std::hash<basic_string<...>> (incoming bikeshed
ahead):
size_t std::hash_raw_chars(const char* ch, size_t len);
size_t std::hash_raw_chars(const wchar_t* ch, size_t len);
size_t std::hash_raw_chars(const char16_t* ch, size_t len);
size_t std::hash_raw_chars(const char32_t* ch, size_t len);
Calling them with nullptr should probably produce the same results as for
empty strings.
Alternatively they could be designed to take templated iterators instead of
the signatures above. Though I assume current implementations are optimized
for contiguous character ranges?

Then the specializations would be redefined in terms of those helper
methods:
template<...>
struct std::hash<basic_string<...>>
{
    size_t operator() (const basic_string<...>& s) { return hash_raw_chars(s
..data(), s.size()); }
};

Now this allows the initial motivation to be rewritten in a much more
efficient manner:
template<>
struct std::hash<MyFancyString>
{
    size_t operator() (const MyFancyString& s) { return hash_raw_chars(s.
dataPointer(), s.length()); }
};
Therefore the std::string "Hello World" and the MyFancyString "Hello World"
both produce the same hash.

This solves two problems: first it makes it very easy to make third-party
string classes (and C char arrays, ugh) compatible with the std::unordered_*containers where
std::string is used as key, and second it eliminates the temporary
std::string instance the current solution requires in this case. When the
std::unordered_* containers (probably) get extended to be less restrictive
in key lookup third-party string types can be very efficiently used to
search in these containers without constructing temporary std::strings,
making this even more useful in environments dealing with heterogenous
string sources.

Looking forward to comments.

Miro

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_5072_31038154.1386038840927
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Greetings,<div><br></div><div>it occurred to me the curren=
t setup of <font face=3D"courier new, monospace">std::hash</font> is not ve=
ry open to extension for foreign string classes. Trying to hash a string co=
ming for example from a third party library the only way to have them achie=
ve the same hash values as <font face=3D"courier new, monospace">std::hash&=
lt;std::string&gt;</font>&nbsp;is by taking a detour using a&nbsp;<font fac=
e=3D"courier new, monospace">std::string</font><font face=3D"arial, sans-se=
rif">&nbsp;temporary</font>.</div><div><br></div><div>A motivational exampl=
e:</div><div><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><=
code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&lt;&gt;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">hash</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">=
MyFancyString</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; =
size_t </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ope=
rator</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;"=
 class=3D"styled-by-prettify">MyFancyString</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> s</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> hash</span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&lt;string&gt;</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{}(</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">s</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">));</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</sp=
an></div></code></div><div>It is also the only way to hash a string coming =
from a C interface, since <font face=3D"courier new, monospace">std::hash&l=
t;char*&gt;</font>&nbsp;hashes the pointer value, not the string pointed to=
..</div><br>This assumes there is a hypothetical conversion from&nbsp;<font =
face=3D"courier new, monospace">MyFancyString</font> to <font face=3D"couri=
er new, monospace">std::string</font> available. This is obviously quite an=
 inefficient solution but the only one I am aware of to hash any sequence o=
f characters using the same implementation as the standard hash. One could =
of course roll out a custom hash implementation and use it consistently but=
 why reinvent the wheel when there already is a hash algorithm for strings =
in the standard? (unless for very special use cases)</div><div><br></div><d=
iv>My idea is to move the actual hashing into freestanding functions, expos=
ing the algorithms used by <font face=3D"courier new, monospace">std::hash&=
lt;basic_string&lt;...&gt;&gt;</font><font face=3D"arial, sans-serif"> (inc=
oming bikeshed ahead):</font></div><div><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187)=
; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpret=
typrint"><font color=3D"#660066"><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">size_t std</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">hash_raw_chars</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> ch</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> size_t len</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span></font><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">size_t std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">hash_raw_chars</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>wchar_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> ch</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> size_t len</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>size_t std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">hash_raw_chars</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> char16_t</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> ch</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> size_t len</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
size_t std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">hash_raw=
_chars</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> char32_t</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> ch</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> size_t len</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">);</span><font color=3D"#660066"><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span></font></div></c=
ode></div></div><div>Calling them with <font face=3D"courier new, monospace=
">nullptr</font> should probably produce the same results as for empty stri=
ngs.</div><div>Alternatively they could be designed to take templated itera=
tors instead of the signatures above. Though I assume current implementatio=
ns are optimized for contiguous character ranges?</div><div><br></div><div>=
Then the specializations would be redefined in terms of those helper method=
s:</div><div><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><=
code class=3D"prettyprint"><div class=3D"subprettyprint"><font color=3D"#66=
0066"><span style=3D"color: #008;" class=3D"styled-by-prettify">template</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;...&gt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">hash</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">basic_string</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;...&gt;&gt;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span></font><span style=3D"color: #000;" class=3D"=
styled-by-prettify">&nbsp; &nbsp; size_t </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">operator</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b=
asic_string</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&lt;...&gt;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> hash</span><font color=3D"#008800"><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">_raw_chars</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">s</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">data</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(),</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> s</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">size=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">())</span>=
</font><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><font color=3D"#660066"><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span></font></d=
iv></code></div></div><div><br></div><div>Now this allows the initial motiv=
ation to be rewritten in a much more efficient manner:<br><div class=3D"pre=
ttyprint" style=3D"background-color: rgb(250, 250, 250); border: 1px solid =
rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&lt;&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">hash</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">MyFancyString</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>&nbsp; &nbsp; size_t </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">operator</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">MyFancyString</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> hash_raw_chars</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">s</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">dataPointer</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(),</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">length</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">());</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span></div></code></div><div>Therefore the <font face=
=3D"courier new, monospace">std::string</font> "Hello World" and the <font =
face=3D"courier new, monospace">MyFancyString</font> "Hello World" both pro=
duce the same hash.<br></div><div><br></div><div>This solves two problems: =
first it makes it very easy to make&nbsp;third-party string classes (and C =
char arrays, ugh) compatible with the <font face=3D"courier new, monospace"=
>std::unordered_*</font> containers where <font face=3D"courier new, monosp=
ace">std::string</font> is used as key, and second it eliminates the tempor=
ary <font face=3D"courier new, monospace">std::string</font> instance the c=
urrent solution requires in this case. When the <font face=3D"courier new, =
monospace">std::unordered_*</font> containers (probably) get extended to be=
 less restrictive in key lookup&nbsp;third-party string types can be very e=
fficiently used to search in these containers without constructing temporar=
y <font face=3D"courier new, monospace">std::string</font>s, making this ev=
en more useful in environments dealing with heterogenous string sources.<br=
></div></div><div><br></div><div>Looking forward to comments.</div><div><br=
></div><div>Miro</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5072_31038154.1386038840927--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Mon, 2 Dec 2013 21:14:06 -0600
Raw View
--f46d04389213d23b6604ec98b24f
Content-Type: text/plain; charset=ISO-8859-1

On 2 December 2013 20:47, Miro Knejp <miro@knejp.de> wrote:

> Greetings,
>
> it occurred to me the current setup of std::hash is not very open to
> extension for foreign string classes. Trying to hash a string coming for
> example from a third party library the only way to have them achieve the
> same hash values as std::hash<std::string> is by taking a detour using a
> std::string temporary.
>

1.  Why does it matter that they have the same hash values?  std::hash
should not be used for fingerprinting.

2.  Being able to hash a string_view will partially solve this problem, at
least for those custom string classes that use contiguous storage.

3.  I'd rather see a more general solution such as Boost's hash_combine and
hash_range <http://www.boost.org/doc/libs/1_55_0/doc/html/hash/combine.html>.
 Strings just aren't that special.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--f46d04389213d23b6604ec98b24f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 2 December 2013 20:47, Miro Knejp <span dir=3D"ltr">&lt=
;<a href=3D"mailto:miro@knejp.de" target=3D"_blank">miro@knejp.de</a>&gt;</=
span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-=
width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddin=
g-left:1ex">

<div dir=3D"ltr">Greetings,<div><br></div><div>it occurred to me the curren=
t setup of <font face=3D"courier new, monospace">std::hash</font> is not ve=
ry open to extension for foreign string classes. Trying to hash a string co=
ming for example from a third party library the only way to have them achie=
ve the same hash values as <font face=3D"courier new, monospace">std::hash&=
lt;std::string&gt;</font>=A0is by taking a detour using a=A0<font face=3D"c=
ourier new, monospace">std::string</font><font face=3D"arial, sans-serif">=
=A0temporary</font>.</div>

</div></blockquote><div><br></div><div>1. =A0Why does it matter that they h=
ave the same hash values? =A0std::hash should not be used for fingerprintin=
g.</div><div><br></div><div>2. =A0Being able to hash a string_view will par=
tially solve this problem, at least for those custom string classes that us=
e contiguous storage.</div>

<div><br></div><div>3. =A0I&#39;d rather see a more general solution such a=
s Boost&#39;s hash_combine and hash_range &lt;<a href=3D"http://www.boost.o=
rg/doc/libs/1_55_0/doc/html/hash/combine.html">http://www.boost.org/doc/lib=
s/1_55_0/doc/html/hash/combine.html</a>&gt;. =A0Strings just aren&#39;t tha=
t special.</div>

</div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a href=3D"mailto=
:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=
=A0 (847) 691-1404
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--f46d04389213d23b6604ec98b24f--

.