I came up with an implementation that overcomes these problems, here
is a usage example:
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : B1, private B2 {};
typedef char Test[SuperSubclass<B, D>::result];
typedef char Test[SuperSubclass<B1,D>::result];
typedef char Test[SuperSubclass<B2,D>::result];
typedef char Test[!SuperSubclass<int,D>::result];
The above code complied fine using Comeau C/C++ 4.3.0.1 and VC7.1
beta.
Without further ado, here is the SuperSubclass implementation:
template <typename B, typename D>
struct SuperSubclass
{
private:
    typedef char (&yes)[1];
    typedef char (&no) [2];
    template<typename T>
    static yes check(D const volatile &, T);    
    static no  check(B const volatile &, int);
    struct C
    {
        operator B const volatile &() const;
        operator D const volatile &();
    };
    static C getC();
public:
    static const bool result = 
        sizeof(check(getC(), 0)) == sizeof(yes);
};
// 
// Additional specializations needed (e.g. void, reference types)
//
template <typename B>
struct SuperSubclass<B, B>
{
    static const bool result = true;
}; 
The implementation is based on an answer by Daveed Vandevoorde to an
overload question: http://tinyurl.com/502f
I also abused the fact that overload resolution prefers non-template
function when it has the same match as function template.
Enjoy,
Rani
      [ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]