Boost logo

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