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.

¿Fue útil?

Solución

Esto se conoce como "análisis sintáctico más irritante C ++ 's". Ver aquí y aquí .

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top