¿Por qué no puedo bajar el puntero a los miembros en argumentos de plantilla?

Si hago un puntero a miembro base, puedo convertirlo en puntero a miembro derivado generalmente, pero no cuando se usa dentro de una plantilla como Buzz a continuación, donde el primer argumento de plantilla influye en el segundo. ¿Estoy luchando contra los errores del compilador o el estándar realmente exige que esto no funcione?

struct Foo
{
    int x;
};

struct Bar : public Foo
{
};

template<class T, int T::* z>
struct Buzz
{
};

static int Bar::* const workaround = &Foo::x;

int main()
{
    // This works. Downcasting of pointer to members in general is fine.
    int Bar::* y = &Foo::x;

    // But this doesn't, at least in G++ 4.2 or Sun C++ 5.9. Why not?
    // Error: could not convert template argument '&Foo::x' to 'int Bar::*'
    Buzz<Bar, &Foo::x> test;

    // Sun C++ 5.9 accepts this but G++ doesn't because '&' can't appear in
    // a constant expression
    Buzz<Bar, static_cast<int Bar::*>(&Foo::x)> test;

    // Sun C++ 5.9 accepts this as well, but G++ complains "workaround cannot
    // appear in a constant expression"
    Buzz<Bar, workaround> test;

    return 0;
}

Respuestas a la pregunta(1)

Su respuesta a la pregunta