www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Failure to discriminate overloads based on most-derived interface

reply "Matthew Wilson" <admin.hat stlsoft.dot.org> writes:
Given the following algorithm:

template Utility(T)
{
    alias NotionalRange!(T)         notional_range_type;
    alias RandomAccessRange!(T)     random_access_range_type;

    size_type r_distance(notional_range_type r)
    in
    {
        assert(null !== r);
    }
    body
    {
        size_type   n   =   0;

        for(; r.is_open; r.advance())
        {
            ++n;
        }

        return n;
    }

    size_type r_distance(random_access_range_type r)
    in
    {
        assert(null !== r);
    }
    body
    {
        return r.length();
    }

} // template Numeric

The compiler fails to select the RandomAccessRange overload of r_distance
when given a range instance that derives from that interface.

The range interface inheritance hierarchy is as follows:

First, the range categories:

interface NotionalRangeTag
{}

    interface IterableRangeTag
        : public NotionalRangeTag
    {}

        interface SubscriptableRangeTag
            : public IterableRangeTag
        {}

            interface RandomAccessRangeTag
                : public SubscriptableRangeTag
            {}

Then the range interfaces:

template NotionalRange(T) { interface NotionalRange
    : public NotionalRangeTag
{
/// \name Member types
///  {
public:
    alias   T                   value_type;
    alias   NotionalRangeTag    range_category;
///  }

/// \name Notional range methods
///  {
public:
    bool        is_open();
    value_type  current();
    void        advance();
///  }
}}

template SubscriptableRange(T) { interface SubscriptableRange
    : public NotionalRange!(T)
    , public SubscriptableRangeTag
{
/// \name Member types
///  {
public:
    alias   NotionalRange!(T)       parent_class_type;
public:
    alias   T                       value_type;
    alias   ptrdiff_t               index_type;
    alias   size_t                  size_type;
    alias   ptrdiff_t               difference_type;
    alias   RandomAccessRangeTag    range_category;
///  }

/// \name Notional range methods
///  {
public:
    bool        is_open();
    value_type  current();
    void        advance();
///  }

/// \name Random access range methods
///  {
public:
    size_type   length();
    value_type  opIndex(index_type index);
    void        advance(difference_type increment);
///  }
}}


template RandomAccessRange(T) { interface RandomAccessRange
    : public SubscriptableRange!(T)
    , public RandomAccessRangeTag
{
}}

Bet you want me to boil that down, eh? :-)
Jul 15 2004
parent "Walter" <newshound digitalmars.com> writes:
"Matthew Wilson" <admin.hat stlsoft.dot.org> wrote in message
news:cd5gg6$1rnv$1 digitaldaemon.com...
 Bet you want me to boil that down, eh? :-)

Yes, please.
Jul 16 2004