Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-01-08 11:21:29


Vladimir Prus <ghost_at_[hidden]> writes:

> 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.
>
>> 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.

There are mostly-transparent solutions. Something like:

    // find_first sequence const version
    template< typename InputT, typename SearchT >
    inline iterator_range< typename InputT::const_iterator >
    find_first_impl( const InputT& Input, const SearchT& Search, 0 )
    {
                ...
    }

    // find_first sequence non-const version
    template< typename InputT, typename SearchT >
    inline iterator_range< typename InputT::const_iterator >
    find_first_impl( InputT& Input, const SearchT& Search, int )
    {
                ...
    }

    // find_first sequence
    template< typename InputT, typename SearchT >
    inline iterator_range< typename InputT::iterator >
    find_first( InputT& Input, const SearchT& Search )
    {
        find_first_impl(Input, Search, 0);
    }

Should work on vc6. Can't vouch for Borland, though :(

-- 
                       David Abrahams
   dave_at_[hidden] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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