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);
}
// 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_.eq ual_range(membe r) );
}
MMIt MemberAt(UserRe ference member, Path path) {
return find(FindMember ships(member), make_pair(membe r,
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<>::iterato r 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? ]
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);
}
// 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_.eq ual_range(membe r) );
}
MMIt MemberAt(UserRe ference member, Path path) {
return find(FindMember ships(member), make_pair(membe r,
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<>::iterato r 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? ]
Comment