
I've just checked in an attempt at supporting built-in arrays in boost::hash. It's not great and I might remove it before Friday. My main problem was that overloading hash_value for both T* and T[Size] causes ambiguity - so I implemented it using partial specialization of call_hash. (If anyone knows how to correctly implement the overload, preferably without SFINAE, let me know, although I'll spend some time looking into it if I can find the time). So I implemented it using partial specialization of hash_detail::call_hash. This breaks the specification of boost::hash_combine, which is specified in terms of boost::hash_value - but boost::hash_value is not overloaded for built in arrays. So it might be a good idea to change it so that it's specified in terms of boost::hash. In a way, I prefer this, since users should never really call hash_value directly and I think the documentation should reinforce this. Any thoughts Peter? Daniel

"Daniel James" <daniel@calamity.org.uk> wrote in message news:d3b7tr$d43$1@sea.gmane.org... | I've just checked in an attempt at supporting built-in arrays in | boost::hash. It's not great and I might remove it before Friday. My main | problem was that overloading hash_value for both T* and T[Size] causes | ambiguity why? Does template< class T > void hash( size_t&, const T* ); template< class T, unsigned N > void hash( size_t&, const T (&array)[N] ); not work? -Thorsten

Daniel James wrote:
I've just checked in an attempt at supporting built-in arrays in boost::hash. It's not great and I might remove it before Friday. My main problem was that overloading hash_value for both T* and T[Size] causes ambiguity - so I implemented it using partial specialization of call_hash. (If anyone knows how to correctly implement the overload, preferably without SFINAE, let me know, although I'll spend some time looking into it if I can find the time).
Indeed it does! I learn something new every day. ;-)
So I implemented it using partial specialization of hash_detail::call_hash. This breaks the specification of boost::hash_combine, which is specified in terms of boost::hash_value - but boost::hash_value is not overloaded for built in arrays.
So it might be a good idea to change it so that it's specified in terms of boost::hash. In a way, I prefer this, since users should never really call hash_value directly and I think the documentation should reinforce this. Any thoughts Peter?
I'd prefer it if hash_value "just works" and does the right thing. If we can't do this, we should probably just drop support for built-in arrays. How about changing the pointer overload to size_t hash_value( void const volatile * p ); ? This doesn't handle pointers to functions, so we'd need a separate overload SFINAEd on is_function; but since hashing function pointers is relatively rare, it won't be a problem if it doesn't work on all compilers. Or perhaps just switching to: template<class T> size_t hash_value( T * const & p ); ?

Peter Dimov wrote:
Or perhaps just switching to:
template<class T> size_t hash_value( T * const & p );
?
How embarrassing....I hadn't thought of that. I was trying every way I could think of to declare the array function. I might not be able to get it to work for older compilers though. But that's not such a big deal. I'll see how it goes. I still think it may be a good idea to change hash_combine's specification (but not necessarily it's implementation) to be in terms of boost::hash (or std::hash). But that's up to you. Thorsten wrote:
Does
template< class T > void hash( size_t&, const T* );
template< class T, unsigned N > void hash( size_t&, const T (&array)[N] );
not work?
It depends on which compiler you ask, intel linux (EDG based) says no. (Sorry, for not replying to your mail directly, but I seem to have lost it, which is a bit odd since I'm using gmane). Daniel

"Daniel James" <daniel@calamity.org.uk> wrote in message news:d3bu0e$6q0$1@sea.gmane.org... | Peter Dimov wrote: | | > Or perhaps just switching to: | > | > template<class T> size_t hash_value( T * const & p ); | > | > ? | | How embarrassing....I hadn't thought of that. I was trying every way I | could think of to declare the array function. I might not be able to get | it to work for older compilers though. But that's not such a big deal. | I'll see how it goes. | | I still think it may be a good idea to change hash_combine's | specification (but not necessarily it's implementation) to be in terms | of boost::hash (or std::hash). But that's up to you. | | Thorsten wrote: | | > Does | > | > template< class T > | > void hash( size_t&, const T* ); | > | > template< class T, unsigned N > | > void hash( size_t&, const T (&array)[N] ); | > | > not work? | | It depends on which compiler you ask, intel linux (EDG based) says no. | (Sorry, for not replying to your mail directly, but I seem to have lost | it, which is a bit odd since I'm using gmane). yeah, there is a macro in boost/range/config.hpp that is more portable: template< class T > void foo( T BOOST_ARRAY_REF()[N] ); as a related issue, an array is a range, so why define hash_value for it? -Thorsten

Thorsten Ottosen wrote:
as a related issue, an array is a range, so why define hash_value for it?
So that you can call hash_combine with an array member, something like struct X { int a; long b[ 4 ]; }; size_t hash_value( X const & x ) { size_t seed = 0; hash_combine( seed, x.a ); hash_combine( seed, x.b ); return seed; }

"Peter Dimov" <pdimov@mmltd.net> wrote in message news:005901c53e6f$4a180fb0$6501a8c0@pdimov2... | Thorsten Ottosen wrote: | > as a related issue, an array is a range, so why define hash_value for | > it? | | So that you can call hash_combine with an array member, something like what if the member is any other range? I'm saying the decision to overload hash_value for arrays seems a bit arbitrary. -Thorsten

Thorsten Ottosen wrote:
what if the member is any other range?
I'm saying the decision to overload hash_value for arrays seems a bit arbitrary.
Ranges that aren't part of the standard can supply their own overloads. The library currently only supports built in types and members of 'std'. Ideally overloads of hash_value for other boost libraries should be contained in the other library (I'm thinking about creating a separate header which contains the bare minimum includes to do this). Daniel

Thorsten Ottosen wrote:
"Peter Dimov" <pdimov@mmltd.net> wrote in message news:005901c53e6f$4a180fb0$6501a8c0@pdimov2...
Thorsten Ottosen wrote:
as a related issue, an array is a range, so why define hash_value for it?
So that you can call hash_combine with an array member, something like
what if the member is any other range?
It should still work, unless the other type (nothing to do with range-ness) does not have a hash_value overload.
I'm saying the decision to overload hash_value for arrays seems a bit arbitrary.
We overload hash_value for every standard container. Array support doesn't seem very arbitrary. You seem a bit obsessed with ranges. ;-)

"Peter Dimov" <pdimov@mmltd.net> wrote in message news:006301c53f46$aead49e0$6501a8c0@pdimov2... | Thorsten Ottosen wrote: | > "Peter Dimov" <pdimov@mmltd.net> wrote in message | > news:005901c53e6f$4a180fb0$6501a8c0@pdimov2... | >> Thorsten Ottosen wrote: | >>> as a related issue, an array is a range, so why define hash_value | >>> for it? | >> | >> So that you can call hash_combine with an array member, something | >> like | > | > what if the member is any other range? | | It should still work, unless the other type (nothing to do with range-ness) | does not have a hash_value overload. well, that a question of definition. | > I'm saying the decision to overload hash_value for arrays seems a bit | > arbitrary. | | We overload hash_value for every standard container. Array support doesn't | seem very arbitrary. | | You seem a bit obsessed with ranges. ;-) yeah, I know :-) -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
| > I'm saying the decision to overload hash_value for arrays seems a bit | > arbitrary. | | We overload hash_value for every standard container. Array support doesn't | seem very arbitrary. | | You seem a bit obsessed with ranges. ;-)
yeah, I know :-)
The need to get a hash value for an array shouldn't create a dependency on the range library. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"Peter Dimov" <pdimov@mmltd.net> writes:
Daniel James wrote:
I've just checked in an attempt at supporting built-in arrays in boost::hash. It's not great and I might remove it before Friday. My main problem was that overloading hash_value for both T* and T[Size] causes ambiguity -
Array types in function parameter lists decay to pointers, so of course that's ambiguous. Maybe you mean template <class T, std::size_t N> size_t hash_value( T (&x)[N] ); ??
so I implemented it using partial specialization of call_hash. (If anyone knows how to correctly implement the overload, preferably without SFINAE, let me know, although I'll spend some time looking into it if I can find the time).
Indeed it does! I learn something new every day. ;-)
I'm very confused. What is "it" and what "does" it do? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Daniel James wrote:
I've just checked in an attempt at supporting built-in arrays in boost::hash. It's not great and I might remove it before Friday. My main problem was that overloading hash_value for both T* and T[Size] causes ambiguity -
Array types in function parameter lists decay to pointers, so of course that's ambiguous. Maybe you mean
template <class T, std::size_t N> size_t hash_value( T (&x)[N] );
??
so I implemented it using partial specialization of call_hash. (If anyone knows how to correctly implement the overload, preferably without SFINAE, let me know, although I'll spend some time looking into it if I can find the time).
Indeed it does! I learn something new every day. ;-)
I'm very confused. What is "it" and what "does" it do?
"It" (overloading on pointer and array) "does" cause ambiguity. template<class T> size_t hash_value( T * p ); template<class T, size_t N> size_t hash_value( T (&a) [N] ); int main() { int a = { 1, 2, 3 }; hash_value( a ); }

"Peter Dimov" <pdimov@mmltd.net> wrote in message news:003f01c53e6d$14615e50$6501a8c0@pdimov2... | David Abrahams wrote: | > I'm very confused. What is "it" and what "does" it do? | | "It" (overloading on pointer and array) "does" cause ambiguity. | | template<class T> size_t hash_value( T * p ); | template<class T, size_t N> size_t hash_value( T (&a) [N] ); | | int main() | { | int a = { 1, 2, 3 }; | hash_value( a ); | } try #include <cstddef> template<class T> size_t hash_value( const T *& p ); template<class T, size_t N> size_t hash_value( T (&a) [N] ); int main() { int a[] = { 1, 2, 3 }; const int b[] = {1,2,3}; hash_value( a ); hash_value( b ); } -Thorsten
participants (4)
-
Daniel James
-
David Abrahams
-
Peter Dimov
-
Thorsten Ottosen