Boost logo

Boost :

From: Pavol Droba (droba_at_[hidden])
Date: 2003-01-08 12:01:35


On Wed, Jan 08, 2003 at 05:10:17PM +0300, Vladimir Prus wrote:
> Hi Pavol,
>
> Pavol Droba wrote:
>
> > I have following two variants of the same function:
> >
> > // find_first sequence const version
> > template< typename InputT, typename SearchT >
> > inline iterator_range< typename InputT::const_iterator >
> > find_first( const InputT& Input, const SearchT& Search )
> > {
> > ...
> > }
> >
> > // find_first sequence non-const version
> > template< typename InputT, typename SearchT >
> > inline iterator_range< typename InputT::iterator >
> > find_first( InputT& Input, const SearchT& Search )
> > {
> > ...
> > }
> >
> > They are two variants of the same algorithm. Difference is that
> > one variant works on const input while the other one is mutable.
> > Difference is also in the return value. One version contains a
> > const_iterator, while the other one a mutable iterator.
> >
> > According to C++ standard it is perfectly legal to have these
> > two variants and feature known as "function template ordering"
> > does the job of choosing the right variant according to an input.
>
> Strictly speaking, I believe that's overload resolution which selects
> the right one.

Not really. Imagine, you have a "const string" as an input. When matching
a template, compiler can use both versions. For the first one, it
substitutes "string" for InputT and for second one "const string".
This is exatly the place there VC7 fails. In the documentation they,
they say, that they do not support function template ordering and
show the very similar example.
 
> > Unfortunately not all compilers can hadle this well. For instance
> > VC7 can't handle it properly.
> >
> > A possible workaround is to rename on of the variants.
> > I have added _mutable suffix to the non-const version.
> >
> > My question is, if it is reasonable to do such a rename for all
> > platforms, or it is better to use a macro and add the suffix only for
> > broken platforms?
>
> I'd prefer the latter variant, so that non-broken platforms use more natural
> syntax. Another question is whether we could use only the second version.
> Theoretically, if you call the second version on const string, then InputT
> should be deduced as "const string". You can then write a simple wrapper to
> select const_iterator or iterator.
>
> The only problem is, IIRC, borland drops "const" on template arguments
> sometimes, and that's not possible to fix. Also, the "simple wrapper" requires
> partial specialization. So, I'm not sure this approach is viable, either.

Currently I'm using the macro approach. But, there is a problem. User code is
not portable. To make it portable, one has to use the macro, and that is even
more clumsier than just a suffix.

Smart wrapper would not help without help of partial specialization, I think.
And this would break VC7 completely. Also I'm not sure how to make a wrapper
which would select the proper return value based on the input.

Adding a suffix has one advantage. It gives a better control over constness. If
user needs just a const_iterator, cons version would work fine even on mutable
input. It mutable iterator is needed, then explicit specification of the algorithm
provides a vital safety check.

Pavol


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk