Subject: Re: [boost] [hash] Turn on BOOST_HASH_NO_IMPLICIT_CASTS by default
From: Daniel James (dnljms_at_[hidden])
Date: 2012-04-17 16:29:17
Thanks for replying. A lot of food for thought.
On 17 April 2012 15:37, Stewart, Robert <Robert.Stewart_at_[hidden]> wrote:
> I applaud your desire to avoid breaking code, but there may be a
> problem. If the header is included in different places with
> different definitions for the macro, won't that violate the ODR?
> All code linked into an application, whether statically or
> dynamically, must use the same definition for the macro. I can
> imagine many scenarios which would violate that precondition
> without warning.
There's actually no ODR risk. The only difference is whether the
function to prevent implicit conversions is present or not. If it
isn't instantiated then the two versions of the header are effectively
identical. If it is instantiated the result is a compile error.
>> A different solution might be to change the implement of
>> Boost.Hash for bools, so that the bool overload isn't
>> required. But that would be treating the sympton, as other
>> implicit casts could cause problems.
> You can make all of the existing overloads into function
> templates and use SFINAE to select the specific type in each
> case. That is, whereas there is now a bool overload, make it a
> function template that uses SFINAE to enable it only when the
> template parameter is bool. That approach would disallow any
> implicit conversions to the built-in types for which there are
> now overloads. That is a breaking change, of course.
I'm not very keen on changing things in the public interface. Also,
I'm still supporting some of the less capable compilers which can be a
bit odd about SFINAE. Although I'm now using SFINAE in the unordered
containers and with a bit effort it's working okay in all the test
I suppose the big question is, which implicit casts should considered
suitable. IIUC your solution has the advantage of only banning certain
implicit casts. Even if I wanted to avoid SFINAE, I could probably
write a type trait to detect them that doesn't rely on it.
I'm not sure if an implicit cast to a class' hash_function would
always be considered safe. For example, someone might supply a lossy
implicit conversion to std::string.
> You could also use std::numeric_limits<T>::is_specialized to
> detect a possibly larger set of types to which overloads in the
> details namespace could be applied.
That's an interesting idea regardless of this issue. But I'm not sure
how much you can infer from a numeric_limits specialisation. My worry
is that someone might specialise it for a class that gives the hash
function problems, something like a big int perhaps.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk