construcción de objetos / Delantero función ambigüedad declaración
-
21-09-2019 - |
Pregunta
Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.
Hola,
No fue sólo por un par de veces que he caído en un estado de construcción de objetos que no entendía, y no fue hasta hoy que me di cuenta de lo que estaba siendo ambigüedad introducida por él. Voy a explicar como se puede reproducir y le gustaría saber si hay una manera de solucionarlo (C ++ 0x permitido). Aquí va.
Supongamos que hay una clase cuyo constructor toma sólo un argumento, y el tipo de éste argumento es otra clase con un constructor por defecto. Por ejemplo:.
struct ArgType {};
class Class
{
public:
Class(ArgType arg);
};
Si intento de construir un objeto de tipo Class
en la pila, consigo una ambigüedad:
Class c(ArgType()); // is this an object construction or a forward declaration
// of a function "c" returning `Class` and taking a pointer
// to a function returning `ArgType` and taking no arguments
// as argument? (oh yeh, loli haets awkward syntax in teh
// saucecode)
Yo digo que es una construcción de objetos, pero el compilador insiste en que es una declaración hacia adelante dentro del cuerpo de la función. Para ustedes que todavía no lo entiende, aquí es un ejemplo completamente de trabajo:
#include <iostream>
struct ArgType {};
struct Class {};
ArgType func()
{
std::cout << "func()\n";
return ArgType();
}
int main()
{
Class c(ArgType());
c(func); // prints "func()\n"
}
Class c(ArgType funcPtr()) // Class c(ArgType (*funcPtr)()) also works
{
funcPtr();
return Class();
}
Así también, suficientes ejemplos. Cualquiera puede ayudar a conseguir todo esto sin hacer nada demasiado anti-idiomática (Soy un desarrollador de la biblioteca, y la gente como bibliotecas idiomáticas)?
- editar
No importa. Esta es una víctima de de análisis más acuciantes: ¿por qué no A bis (() ); trabajar? .
Gracias, OSE.
Otros consejos
Vamos a simplificar un poco.
int f1();
¿Qué es eso? El compilador (y yo) dicen que es una declaración hacia adelante para una función que devuelve un entero.
¿Qué tal esto?
int f2(double );
El compilador (y yo) digo que es una declaración hacia adelante para una función que toma un argumento doble y devolver un int.
Así que has esto:
ClassType c = ClassType(ArgType());
Salida de C ++ FAQ Lite en constructores de explicaciones y ejemplos
Sobre la base de la "C ++ 0x permitido", la respuesta correcta es (probablemente) para cambiar la definición de:
Class c(ArgType {});
simple, directo y pone la carga por completo en el usuario de la biblioteca, no el autor!
Edit: Sí, el ctor se invoca - C ++ 0x añade Lista-inicialización como una forma no ambigua para delimitar las listas de inicializador. No puede ser mal analizados como en la muestra, pero por lo demás el significado es más o menos lo mismo que si se ha utilizado paréntesis. Ver N3000 , el tercer punto punto bajo §8.5.4 / 3. Puede escribir un ctor para recibir una lista de inicialización como un solo argumento, o los elementos de la lista de inicialización se puede emparejar con los argumentos ctor individualmente.