Wenn ich ein Zeiger-zu-Basis-Mitglied mache, kann ich es normalerweise in ein Zeiger-zu-abgeleitetes-Element konvertieren, aber nicht innerhalb einer Vorlage wie Buzz unten, wo das erste Template-Argument das zweite beeinflusst. Bekämpfe ich Compilerfehler oder schreibt der Standard wirklich vor, dass dies nicht funktioniert?Warum kann ich Zeiger in Vorlagenargumenten nicht auf Mitglieder reduzieren?
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;
}
Definitiv richtig, aber jede Idee, warum es nicht erlaubt ist? Scheint willkürlich. –
@Joseph: Ich dachte es auch, weshalb ich auch C++ 0x überprüft habe. (Sie haben viele scheinbar willkürliche Entscheidungen entfernt, wie etwa keine Standardschablonenparameter für Funktionsschablonen.) Entweder hat niemand eine Verwendung dafür gefunden und so hat es sich nicht wirklich geändert/so wurde es einfach nicht gedrängt (es ist einfacher, einen Brunnen hinzuzufügen). Funktion getestet, als eine defekte Funktion abzulehnen), oder es gibt einen Grund, warum ich einfach nicht sehen kann. – GManNickG