|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2005-02-27 09:33:39
The following message is a courtesy copy of an article
that has been posted to comp.lang.c++.moderated as well.
[I'm Cc'ing this to Boost because IIRC some people were struggling
with a similar issue recently. Of course it may not apply ;-)]
"Nicolas" <nicolas.tisserand_at_[hidden]> writes:
> Ben Hutchings wrote:
>
> [snip]
>> I believe it was considered unreasonable to require implementers to
>> do that kind of analysis, given that it could involve checking for
>> specialisations across the whole program.
>
> Got that. Thanks :)
>
> In the code I posted, I was trying to specialize a class template
> (IteratorTraits) according to the relationship between an Iterator and
> its Container.
> For instance, I wanted to be able to produce a specialization of
> IteratorTraits for what std::vector<T, Alloc> advertises as being its
> iterator type.
It's fundamentally impossible [unless the core language was to make
exceptions based on special knowledge about certain standard library
components]. Forget everything you know about vectors, and now
consider:
template <class Iterator>
struct IteratorTraits;
template <class T>
struct vector
{
typedef char* iterator;
};
// This would be the syntax, if it were legal.
template <class T>
struct iterator_traits<vector<T>::iterator>
{
// What is T?
};
It's illegal because there's no way for the compiler to deduce T.
> Is there a way to do that without having to examine a given STL
> implementation and find out what the exact type of std::vector<T,
> Alloc>::iterator is?
Technically, no.
*If* you're willing to assume that std::vector<T,A>::iterator is the
same type for any A (which is not quite correct in any real
implementation because of vector<bool>), you could do this:
template <class Iterator, class Enable = void>
struct IteratorTraits;
template <class Iterator>
struct IteratorTraits<
Iterator
, boost::enable_if<
boost::is_same<
Iterator
, typename std::vector<
typename std::iterator_traits<Iterator>::value_type
>::iterator
>
>::type
>
{
// whatever you want here.
};
This specialization of IteratorTraits applies iff the iterator type of
a vector of the argument's value_type is the same as the argument.
I'm sure you can figure out how to deal with the vector<bool> anomaly.
See http://www.boost.org/libs/utility/enable_if.html for information
about how enable_if works with class template specializations.
HTH,
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk