Por qué no puedo abatido puntero a los miembros de argumentos de plantilla?
-
26-09-2019 - |
Pregunta
Si hago un-miembro-puntero a base, I se puede convertir a un puntero a miembro derivado generalmente, pero no cuando se utiliza dentro de una plantilla como zumbido de abajo, donde la primera plantilla de argumentos influencias el segundo . Estoy luchando errores de compilación o no la norma realmente mandato esto no trabajo?
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;
}
Solución
No está permitido simplemente. Según §14.3.2 / 5:
Los siguientes conversiones se realizan en cada expresión utilizada como un no-tipo de plantilla-argumento. Si una plantilla-argumento que no es de tipo no se puede convertir en el tipo del-parámetro de plantilla correspondiente, entonces el programa está enfermo formado.
.
- para una plantilla-parámetro no tipo de tipo integral o enumeración, promociones integral (4.5) y las conversiones integrales (4.7) se aplican
. - para una plantilla-parámetro no tipo de tipo puntero a objeto, se aplican las conversiones de calificación (4.4) y la conversión-array-a puntero (4.2). - Para una plantilla-parámetro no tipo de referencia de tipo de objeto, no se aplican las conversiones. El tipo mencionado por la referencia puede ser más cv-cualificado que el tipo (por lo demás idéntico) del argumento plantilla. El parámetro de plantilla se une directamente a la plantilla-argumento, que debe ser un valor-I.
- Para una plantilla-parámetro no tipo de tipo puntero a función, sólo se aplica la conversión-function-a puntero (4.3). Si la plantilla-argumento representa un conjunto de funciones sobrecargadas (o un puntero a tales), la función de emparejamiento se selecciona entre el conjunto (13.4).
- Para una plantilla-parámetro no tipo de referencia de tipo de función, no se aplican las conversiones. Si la plantilla-argumento representa un conjunto de funciones sobrecargadas, la función de emparejamiento se selecciona entre el conjunto (13.4).
- Para una plantilla-parámetro no tipo de tipo puntero a función miembro, no se aplican las conversiones. Si la plantilla-argumento representa un conjunto de funciones miembro sobrecargados, la función miembro correspondiente se selecciona entre el conjunto (13.4).
- Para una plantilla-parámetro no tipo de puntero tipo de miembro de datos, las conversiones de calificación (4.4) se aplican
he hizo hincapié en la conversión con respecto a los miembros de datos de puntero. Tenga en cuenta que su conversión (§4.11 / 2) no está en la lista. En C ++ 0x, sigue siendo el mismo en este sentido.