2011-08-03 16 views

Respuesta

13

Para mí, la plantilla de C++ utilizaba la idea de pato escribir, ¿es esto correcto?

No, las plantillas C++ se utilizan para implementar código genérico. Es decir, si tiene un código que puede funcionar con más de un tipo, no tiene que duplicarlo para cada tipo. Cosas como std::vector y std::list son ejemplos obvios de esto en acción. C++ plantillas have been abused para hacer otras cosas, pero la originalidad fue la intención original.

¿Significa que todos los tipos genéricos a los que se hace referencia en la clase de plantilla o el método son de tipo pato?

No, son simplemente tipos "normales" como cualquier otro tipo en C++. Simplemente no se conocen hasta que la plantilla se haya instanciado realmente.

Sin embargo, las plantillas se pueden utilizar para implementar algo como escribiendo patos. Iteradores son un ejemplo. Considere esta función:

template<class InputIterator, class OutputIterator> 
    OutputIterator copy(InputIterator first, InputIterator last, 
         OutputIterator result) 
{ 
    while (first!=last) *result++ = *first++; 
    return result; 
} 

Tenga en cuenta que la función copy puede aceptar los argumentos de cualquier tipo , como a lo largo ya que implementa el operador de desigualdad, el operador eliminar la referencia, y el operador de incremento de sufijo. Esto es probablemente lo más parecido a la mecanografía de pato que obtendrás en C++.

+7

Desde mi limitada comprensión de pato a escribir, su descripción de la copia-función, precisamente, suena como si se utiliza de pato a escribir. ¿Qué es exactamente lo que caracteriza el tipado de patos que no se "cumple" con las plantillas de C++? – aioobe

+5

@aioobe: Según entiendo, el tipado de patos es algo que ocurre en tiempo de ejecución en lugar de en tiempo de compilación. Digo que es como el tipado de patos porque el compilador aún hace la verificación de tipos en tiempo de compilación, como si no estuviera haciendo ningún tipo de pato. Es solo que los tipos no se conocen hasta que uno realmente usa la plantilla. –

+0

Desde el punto de vista de la creación de instancias de la plantilla, la distinción en tiempo de compilación/tiempo de ejecución corresponde a la preinstalación y post-instanciación. En mi humilde opinión, la distinción tiempo de compilación/tiempo de ejecución tal vez se considere mejor como una instancia de una distinción 'tiempo de compilación/tiempo de compilación' (es decir, 'el comportamiento se conoce/decide en o antes del tiempo de compilación' vs 'después') . Donde eg. python comprueba al llamar a object.hello(), no al compilar a bytecode, C++ comprobará cuando intente compilar Type1 y object :: hello (Type1 x, Type2 y) {return x + y; } en vez de convertir c = object.hello (a, b); dentro de esto. –

3

Sí, más o menos - por ejemplo, si el tipo de X tiene AddRef(), Release() y QueryInterface() métodos con las firmas correspondientes que puede ser utilizado como un objeto COM con la clase CComPtr plantilla. Pero esto no es una tipificación completa del pato: la verificación del tipo aún se aplica a los parámetros.

2

No, este es un concepto diferente. la tipificación de pato es un método para averiguar el tipo de contenedor de tipo dinámico. Las plantillas de C++ no tienen un tipo dinámico, se instancian con un tipo específico.

4

No exactamente. Los tipos de pato (estilo de tipo dinámico) nunca arrojarán errores de tipo de tiempo de compilación porque simplemente no tienen ningún tipo. Con las plantillas, no tiene tipos hasta que cree una instancia de la plantilla. Una vez que lo haga, las variables tienen distintos tipos, y de hecho obtendrá errores en tiempo de compilación.

Además, con los tipos de pato, puede tener un punto variable para diferentes tipos de objetos, porque las variables simplemente no tienen ningún tipo. Eso no es posible con las plantillas: una vez que las crea, las variables tienen un único tipo específico.

Son similares, sin embargo, en que las restricciones son implícitas: solo se comprueban las características realmente utilizadas. A diferencia de, digamos, punteros polimórficos, el tipo real no importa.

59

Para mí, las plantillas de C++ son una versión en tiempo de compilación de mecanografía de pato. El compilador compilará, p. Clase y siempre y cuando su Duck tenga todos los tipos necesarios creará una instancia de una clase.

Si algo no es correcto (por ejemplo, falta el constructor de copia) la compilación falla. La contraparte en Duck Typing real es un fracaso cuando se llama a una función con un tipo no pato. Y aquí ocurriría en tiempo de ejecución.

+0

hmm ... mi comprensión de la mecanografía pato es que intentas averiguar el tipo. Eso significa que encuentras un objeto dinámico y no estás seguro del tipo. En las plantillas de C++, debe estar seguro del tipo para poder crear una instancia. – duedl0r

+4

-1. Duck typing no implica necesariamente tipeo dinámico o verificaciones en tiempo de ejecución. El tipeo de pato en tiempo de compilación todavía es tipado de pato. –

+0

Las plantillas de C++ se basaban originalmente en la reproducción de token. Eso todavía se muestra en sus propiedades tipo pato. –

10

Duck typing significa, "si grazna como un pato y camina como un pato, entonces es un pato". No tiene una definición formal en informática para nosotros para comparar C++ en contra.

C++ no es idéntico (por ejemplo) a Python, por supuesto, pero ambos tienen un concepto de interfaces implícitamente definidas. La interfaz requerida de un objeto utilizado como argumento de la función Python es lo que sea que la función haga con ella. La interfaz requerida de un tipo utilizado como argumento de plantilla C++ es lo que haga la plantilla con los objetos de ese tipo. Esa es la similitud, y esa es la base sobre la que deben evaluarse las plantillas de C++.

Además, debido a la deducción del argumento de la plantilla, en C++ puede intentar pasar cualquier objeto antiguo, y el compilador determinará si puede crear una instancia de la plantilla de la función.

Una diferencia es que en C++, si el argumento no grazna, entonces el compilador se opone. En Python, solo los objetos de tiempo de ejecución (y solo si realmente se llama a la función, si hay condicionales en el código). Esta es una diferencia en la naturaleza de la interfaz demandada de un objeto/tipo: en C++, o bien la plantilla requiere que una expresión en particular sea válida o no lo requiere. En Python, las expresiones válidas necesarias pueden depender de los valores de tiempo de ejecución de las expresiones necesarias anteriores. Entonces, en Python puedes pedir un objeto que grazna fuerte o silenciosamente, y si grazna fuerte también necesita caminar. En C++ puede hacerlo mediante un dynamic_cast condicional, y si el volumen es una constante en tiempo de compilación, puede hacerlo con especializaciones de plantilla, pero no puede usar el tipado estático para decir que un pato solo necesita caminar si quack_volume() devuelve loud. Y, por supuesto, en Python la interfaz requerida puede no ser realmente "requerida": el comportamiento si un método no está presente es lanzar una excepción, y podría ser posible documentar y garantizar el comportamiento de la persona que llama si eso sucede.

Depende de usted si define "pato escribiendo" para que esta diferencia signifique que C++ no lo tiene.

Cuestiones relacionadas