programa - ¿Cuál es la relación entre la plantilla de C++ y la tipificación de pato?
tipos de datos en c++ (7)
Para mí, la plantilla de C ++ utilizó la idea de tipar pato, ¿es así?
No, las plantillas de 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. Las plantillas de C ++ han sido abusadas 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 clase de plantilla o 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 así como escribir pato. Iteradores son un ejemplo. Considera 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 de copy
puede aceptar argumentos de cualquier tipo , siempre que implemente el operador de desigualdad, el operador de desreferencia y el operador de incremento postfix. Esto es probablemente lo más parecido a la mecanografía de pato que obtendrás en C ++.
Para mí, la plantilla de C ++ utilizó la idea de tipar pato, ¿es así? ¿Significa que todos los tipos genéricos a los que se hace referencia en clase de plantilla o método son de tipo pato?
Duck typing significa, "si canta 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 viejo, 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 ++ puedes hacer eso mediante un dynamic_cast
condicional, y si el volumen es una constante en tiempo de compilación, puedes hacerlo con especializaciones de plantilla, pero no puedes usar el tipado estático para decir que un pato solo necesita caminar si quack_volume()
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.
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 verifican las características realmente utilizadas. A diferencia de, digamos, punteros polimórficos, el tipo real no importa.
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.
Para mí, las plantillas de C ++ son una versión en tiempo de compilación de tipado de pato. El compilador compilará, por ejemplo, Clase y siempre que tu Pato tenga todos los tipos necesarios creará una instancia de una clase.
Si algo no está correcto (por ejemplo, falta el constructor de copia) la compilación falla. La contraparte en pato real es una falla cuando llama a una función con un tipo que no sea de pato. Y aquí ocurriría en tiempo de ejecución.
Sí, más o menos, por ejemplo, si el tipo X
tiene métodos AddRef()
, Release()
y QueryInterface()
con las firmas adecuadas, se puede usar como un objeto COM con la clase de plantilla CComPtr
. Pero esto no es una tipificación completa del pato: la verificación del tipo aún se aplica a los parámetros.
Wikipedia cubre esta distinción .