2010-12-27 20 views
8

OK, antes de darme clases sobre el uso de funciones variadic de estilo C en C++ ... todo lo demás ha resultado requerir nada más que volver a escribir el Qt MOC.funciones Qt y variadic

Lo que me gustaría saber es si puede o no tener un "espacio" en un objeto Qt que tome una cantidad arbitraria/tipo de argumentos. Lo que pasa es que realmente quiero poder generar objetos Qt que tengan ranuras de una firma arbitraria. Como el MOC es incompatible con el preprocesamiento estándar y con plantillas, no es posible hacerlo con un enfoque directo. Sólo vine otra idea:

struct funky_base : QObject 
{ 
    Q_OBJECT 
    funky_base(QObject * o = 0); 

public slots: 
    virtual void the_slot(...) = 0; 
}; 

Si esto es posible, entonces, porque se puede hacer una plantilla que es una subclase de un objeto QObject derivadas siempre y cuando no se declara cosas nuevas Qt en ella, Debería poder implementar un tipo de plantilla derivada que tome el material ... y lo convierta en los tipos esperados apropiados.

Si es así, ¿cómo me conectaría? ¿Esto funcionaría?

connect(x, SIGNAL(someSignal(int)), y, SLOT(the_slot(...))); 

Si nadie ha intentado algo tan loco y no sabe fuera de la mano, sí, lo que finalmente va a probar en mi misma ... pero estoy esperando que alguien los conocimientos ya existentes que puede tocar antes de perder posiblemente mi tiempo en eso.


Esta pregunta fue un intento de encontrar una manera de diseñar una clase base 'catch-all' para un objeto de plantilla que podría traducir las señales de Qt en señales estáticas como impulso :: signals2 o funciones básicas justas. Pensé que si podía construir una ranura que tomara plantillas variadas podría usar TMP para reconstruir los parámetros de los va_args. La respuesta al problema fue exactamente eso, pero se recorta ANTES de que el mecanismo de qt llame a la ranura. La primera entrega de una serie de artículos sobre cómo hacer que todo el asunto mostró cómo resolví esta parte del problema:

http://crazyeddiecpp.blogspot.com/2011/01/quest-for-sane-signals-in-qt-step-1.html

Esa es mi lugar antiguo blog. Nuevo en mi perfil si quieres ver otro sh1t extraño.

+2

NVM, respondí mi propia pregunta. Qt por supuesto no puede hacer esto tampoco. –

+1

Al tener slots sin tipo está regalando una de las principales ventajas del lenguaje ... seguridad del tipo de tiempo de compilación. –

+2

Frank, franco, franco. Qt ya lo hizo. Estoy tratando de recuperar la seguridad tipográfica. Este fue un intento fallido. Ver mi blog para la historia de éxito final (está en mi perfil). –

Respuesta

2

Aparentemente, la gente sigue pensando que esta pregunta todavía necesita respuesta porque varias semanas después de que la pregunté y luego la respondí yo mismo, la gente sigue publicando sus respuestas. Así que supongo que tengo que hacer explícitamente una respuesta en lugar de ambas en la pregunta en sí y el primer comentario:

No se puede usar una función variadica como señal o ranura en Qt.

Pasé mucho tiempo y esfuerzo no solo resolviendo el problema y compartiéndolo, sino explicando CÓMO se resolvió el problema. Por favor, considere leer, incluso podría aprender algo nuevo.

+1

No es un problema en SO para responder a su propia pregunta;) –

1

Todo para resolver este problema será feo, pero no deberías tener que hacer todo el trabajo pesado por ti mismo. Puede usar boost::any o boost::variant como tipo de argumento y luego hacer rodar un objeto para contener los argumentos que necesita (o usar un vector de cualquier/tipos de variantes).

También puede usar QVariant, pero no es tan bueno como boost :: variant, y ciertamente no tan flexible (por un precio) como boost :: any.

(O simplemente reescriba Qt con boost :: signals o la variante trX ::, ya que ahora vivimos en el siglo 21. Además, en realidad no moleste demasiado a los desarrolladores de Qt por el estado de las señales/ranuras - las características de C++ - que impulsan :: los usos de las señales no eran comúnmente compatibles con los compiladores de C++ cuando Trolltech desarrolló su implementación de señal/ranuras).

-1

Tenga en cuenta que las construcciones "..." no pueden tomar objetos "reales", porque C++ nunca se molestó en extender la sintaxis "...".

Eso es realmente una buena noticia en su caso, porque significa que la siguiente sugerencia podría funcionar para usted sin tener que preocuparse por la destrucción automática de sus objetos por parte de C++.

Lo que puedes hacer es crear un objeto simple cuyo constructor toma un "...".Analizaría sus argumentos, vertiéndolos en una matriz dinámicamente asignada. Entonces podrías pasar ese único objeto a la ranura.

Digamos que usted es un mecanógrafo perezoso y llamó a ese objeto V (por variante o variadic o lo que sea). Posteriormente, se podría llamar a una función que toma V de esta manera:

function(V("one", "two", "three", NULL)); 

Por supuesto, cada persona que llama tendría que construir V con la mano, que tal vez no es exactamente lo que usted esperaba.

+0

No voté esto, pero "no tener que preocuparme por la autodestrucción de objetos de C++" es una afirmación bastante peligrosa. De lo contrario, estaría de acuerdo en su mayor parte. Se supone que los objetos C++ con destructores se destruyen automáticamente. No tener eso es pasar por alto un mecanismo fundamental en el lenguaje. – stinky472