C
Chandra Shekhar Kumar
Paul said:Hi
Template partial specialization always seems like a fairly
straightforward concept - until I try to do it .
I am trying to implement the input sequence type (from Stroustrup
section 18.3.1, 'Iseq'). I want the version for containers that he
gives, but also to provide a specialization for construction from a
pair<It,It> (eg because that is returned by equal_range()). [Iseq is
actually implemented as a pair<> - but that is a separate issue.]
Here is what I have:
// ---------------------------------------------------------------
// A type representing an 'input sequence':
template<class In>
class Iseq : public pair<In, In> {
public:
Iseq(In i1, In i2) : pair<In, In>(i1, i2) {}
bool IsEmpty() const { return first == second; }
};
// A helper function to make one (since ctors can't
// infer the types of template arguments):
template<class C>
Iseq<typename C::iterator> iseq(C& c) {
return Iseq<typename C::iterator>(c.begin(), c.end());
}
// A specialisation for pairs:
template<class T>
Iseq<T> iseq_p(pair<T, T> p) {
return Iseq<T>(p.first, p.second);
}
this is not specialisation of class Iseq for pairs if u replace iseq_p
with Iseq. it is a function.
the specialisation is:
template <>
template <class T>
class Iseq<pair<T,T> >
{
public:
Iseq(pair<T,T> pairv): pair<T,T>(pairv.first, pairv.second)
};
this is not the solution to yr problem though, but it will give u the
basic idea.
// An overloaded version of STL find() taking an input sequence:
template<class In, class T>
In find(Iseq<In> r, const T& v) { return find(r.first, r.second, v);
}
// And finally, a client:
Iseq<MMIt> FindMemberships(UserReference member) {
return iseq_p( memberships_.equal_range(member) );
}
MMIt MemberAt(UserReference member, Path path) {
return find(FindMemberships(member), make_pair(member,
path));
}
// ---------------------------------------------------------------
This works. But only because I have renamed my 'specialisation' of
iseq() for pairs to iseq_p. I don't want to (and don't think I have
to) do that, for this or any further specialisations. Simply replacing
'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
attempt to use the first definition of iseq, and it (rightly)
complains that pair<>::iterator does not exist. What mistake am I
making?
[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
might be inclined to make it privately inherit it - surely no client
wants to use the pair<> interface? ]