Si je crée un pointeur vers un membre de base, je peux le convertir en un membre pointeur-dérivé, mais pas quand il est utilisé dans un modèle comme Buzz ci-dessous, où le premier argument influence le second. Est-ce que je me bats les bogues du compilateur ou est-ce que la norme exige vraiment que cela ne fonctionne pas?Pourquoi ne puis-je pas rediriger le pointeur vers des membres dans les arguments de modèle?
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;
}
Tout à fait raison, mais aucune idée pourquoi ce n'est pas autorisé? Cela semble arbitraire. –
@Joseph: Je pensais que c'était aussi, c'est pourquoi j'ai aussi vérifié C++ 0x. (Ils ont supprimé de nombreuses décisions apparemment arbitraires, comme aucun paramètre de modèle par défaut pour les modèles de fonction.) Soit personne n'a trouvé d'utilisation pour cela et donc il n'a pas vraiment changé/donc il n'a simplement pas été poussé (il est plus facile d'ajouter un fonctionnalité testée que de déprécier une fonctionnalité cassée), ou il y a une raison fondamentale que je ne peux pas voir. – GManNickG