Array in Unordered Map

Hi, What's the right way to get an array into an unordered map? This one works on VC10, but GCC appears to look for the hash_value function in namespace std. What's the right way to do this? Olaf #include <array> #include <boost/unordered_map.hpp> namespace boost { template<class T, size_t N> size_t hash_value(const std::array<T, N>& v) { return boost::hash_range(v.begin(), v.end()); } } int main() { boost::unordered_map<std::array<char, 20>, int> c; c[std::array<char, 20>()] = 0; return 0; } -- Olaf

On 30 April 2012 18:12, Olaf van der Spek <ml@vdspek.org> wrote:
Hi,
What's the right way to get an array into an unordered map?
This one works on VC10, but GCC appears to look for the hash_value function in namespace std. What's the right way to do this?
As far as I know gcc is correct. Functions are only visible if they're available at the point of the call to hash_value in the source code, or via ADL at the point of instantiation. So you need to do one of: a) write hash_value before including the hash header, b) write hash_value in the std namespace, c) specialize boost::hash, d) use trunk, which supports std::array or e) patch your copy of boost. 'a' is pretty fragile, 'b' isn't standards compliant, 'd' and 'e' might not be possible so 'c' is possibly the best thing to do - it also won't clash with boost::hash_value when boost 1.50 is released. Specializing boost::hash isn't really recommended in general, but if there's no other solution...

On Mon, Apr 30, 2012 at 10:11 PM, Daniel James <dnljms@gmail.com> wrote:
On 30 April 2012 18:12, Olaf van der Spek <ml@vdspek.org> wrote:
Hi,
What's the right way to get an array into an unordered map?
This one works on VC10, but GCC appears to look for the hash_value function in namespace std. What's the right way to do this?
As far as I know gcc is correct. Functions are only visible if they're available at the point of the call to hash_value in the source code,
Are both VC10 and VC11 broken then?
or via ADL at the point of instantiation. So you need to do one of: a) write hash_value before including the hash header,
A bit hard, as I need hash_range().
b) write hash_value in the std namespace,
Doesn't work with VC10. c) specialize boost::hash, d) use trunk, which
supports std::array or
Not an option, the software should be compilable on Debian, CentOS, RHEL, etc.
e) patch your copy of boost.
See D
'a' is pretty fragile, 'b' isn't standards compliant, 'd' and 'e' might not be possible so 'c' is possibly the best thing to do - it also won't clash with boost::hash_value when boost 1.50 is released. Specializing boost::hash isn't really recommended in general, but if there's no other solution...
I'll give C a try, thanks. -- Olaf

On 30 April 2012 22:02, Olaf van der Spek <ml@vdspek.org> wrote:
On Mon, Apr 30, 2012 at 10:11 PM, Daniel James <dnljms@gmail.com> wrote:
On 30 April 2012 18:12, Olaf van der Spek <ml@vdspek.org> wrote:
Hi,
What's the right way to get an array into an unordered map?
This one works on VC10, but GCC appears to look for the hash_value function in namespace std. What's the right way to do this?
As far as I know gcc is correct. Functions are only visible if they're available at the point of the call to hash_value in the source code,
Are both VC10 and VC11 broken then?
Maybe, I'm not expert enough to say for sure. 'broken' is quite a harsh way to describe it. I think Microsoft tends to prioritize supporting existing code over strict standards compliance (which is perhaps one of the reasons they've been so successful in the business world).
or via ADL at the point of instantiation. So you need to do one of: a) write hash_value before including the hash header,
A bit hard, as I need hash_range().
There's a forward declaration in <boost/functional/hash/hash_fwd.hpp> (ah, it's undocumented, I just created a ticket at https://svn.boost.org/trac/boost/ticket/6849).

On Tue, May 1, 2012 at 12:08 PM, Daniel James <dnljms@gmail.com> wrote:
As far as I know gcc is correct. Functions are only visible if they're available at the point of the call to hash_value in the source code,
Are both VC10 and VC11 broken then?
Maybe, I'm not expert enough to say for sure. 'broken' is quite a harsh way to describe it. I think Microsoft tends to prioritize supporting existing code over strict standards compliance (which is perhaps one of the reasons they've been so successful in the business world).
True, I meant broken as in not accepting the code I posted. Is there any way to make it work with both GCC and VC (while using hash_value)? Olaf

On 1 May 2012 12:08, Olaf van der Spek <ml@vdspek.org> wrote:
On Tue, May 1, 2012 at 12:08 PM, Daniel James <dnljms@gmail.com> wrote:
Maybe, I'm not expert enough to say for sure. 'broken' is quite a harsh way to describe it. I think Microsoft tends to prioritize supporting existing code over strict standards compliance (which is perhaps one of the reasons they've been so successful in the business world).
True, I meant broken as in not accepting the code I posted. Is there any way to make it work with both GCC and VC (while using hash_value)?
AFAIK only by controlling the source order, which is pretty flimsy. The customization mechanism isn't great for a namespace you don't own.

[Daniel James]
I think Microsoft tends to prioritize supporting existing code over strict standards compliance
In the STL, I will happily break user code in the pursuit of conformance. ("Because the Standard told us to" is a very effective response.) For example, VC10 implemented C++11's immutable sets - a breaking change from C++98/03 - with no escape hatch. Even the compiler does this from time to time. For example, VC used to take shortcuts in the conditional operator, avoiding the generation of temporaries that were technically required by the Standard. This didn't cause major problems until the addition of rvalue references, where the shortcuts led to unintentional stealing from lvalues (basically, the end of the world). So the conditional operator was fixed to strictly follow the Standard - making rvalue references happy, but breaking user code that tried to perform certain wacky conversions (prohibited by the conditional operator's rules). Stephan T. Lavavej Visual C++ Libraries Developer
participants (3)
-
Daniel James
-
Olaf van der Spek
-
Stephan T. Lavavej