I want to define std::tr1::hash<boost::tuple<A,B,C> >. But I get an error that doesn’t appear when I give a complete instantation. Here’s the code
namespace std{
namespace tr1{
template<typename A, typename B, typename C>
struct hash<boost::tuple<A,B,C> >{
size_t operator()(const boost::tuple<A,B,C> &t) const{
size_t seed = 0;
boost::hash_combine(seed, t.get<0>());
boost::hash_combine(seed, t.get<1>());
boost::hash_combine(seed, t.get<2>());
return seed;
}
};
template<>
struct hash<boost::tuple<int,int,int> >{
size_t operator()(const boost::tuple<int,int,int> &t) const{
size_t seed = 0;
boost::hash_combine(seed, t.get<0>());
boost::hash_combine(seed, t.get<1>());
boost::hash_combine(seed, t.get<2>());
return seed;
}
};
}
}
The first piece gives this error
unordered.hpp: In member function 'size_t std::tr1::hash<boost::tuples::tuple<A, B, C, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >::operator()(const boost::tuples::tuple<A, B, C, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>&) const':
unordered.hpp:12: error: expected primary-expression before ')' token
unordered.hpp:13: error: expected primary-expression before ')' token
unordered.hpp:14: error: expected primary-expression before ')' token
and the second compiles just fine. What’s wrong with the first template? I’m using gcc 4.3.4.
You need to use the
.templatekeyword:This is required because type of
tdepends on three template paramaters (and sotis type-dependent), andget<0>is the name of a template specialization. From the C++ standard —§14.2/4:This requirement exists to allow templates to be parsed before their type arguments are known.
For example, consider:
Without the
.templaterule, this could interpreted as two different things:The actual rules allow
f . set < 0 > ( 2 == 3 )to be unambiguously parsed as a series of comparison operations. They also mean thatt.get<0>()is parsed ast.get < 0 > (). Theexpected primary-expressionis meant to be in the empty().