Si hago un puntero-a-miembro-base, puedo convertirlo generalmente en un puntero-a-miembro-derivado, pero no cuando lo uso 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?¿Por qué no puedo bajar el puntero a miembros en argumentos de plantilla?
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;
}
Definitivamente, ¿pero alguna idea de por qué no está permitido? Parece arbitrario. –
@Joseph: pensé que también, por lo que también revisé C++ 0x. (Eliminaron muchas decisiones aparentemente arbitrarias, como no tener parámetros de plantilla predeterminados para las plantillas de funciones). O nadie encontró un uso para él y, por lo tanto, no ha cambiado realmente/simplemente no se presionó (es más fácil agregar un pozo). característica probada que desaprobar una característica rota), o hay alguna razón fundamental que simplemente no puedo ver. – GManNickG