C ++ 0x agrega un soporte de inferencia de tipos bastante completo. Estoy muy tentado a usarlo en todos los lugares posibles para evitar una repetición indebida, pero me pregunto si eliminar la información de tipo explícita en todo el lugar es una buena idea. Considere este ejemplo bastante artificial:
Foo.h
:
#include <set>
class Foo {
private:
static std::set<Foo*> instances;
public:
Foo();
~Foo();
// What does it return? Who cares! Just forward it!
static decltype(instances.begin()) begin() {
return instances.begin();
}
static decltype(instances.end()) end() {
return instances.end();
}
};
Foo.cpp
:
#include <Foo.h>
#include <Bar.h>
// The type need only be specified in one location!
// But I do have to open the header to find out what it actually is.
decltype(Foo::instances) Foo::instances;
Foo() {
// What is the type of x?
auto x = Bar::get_something();
// What does do_something() return?
auto y = x.do_something(*this);
// Well, it's convertible to bool somehow...
if (!y) throw "a constant, old school";
instances.insert(this);
}
~Foo() {
instances.erase(this);
}
¿Diría que esto es razonable o es completamente ridículo? Después de todo, especialmente si está acostumbrado a desarrollar en un lenguaje dinámico, realmente no necesita preocuparse demasiado por los tipos de cosas, y puede confiar en que el compilador detectará cualquier abuso atroz del sistema de tipos. Pero para aquellos de ustedes que confían en el soporte del editor para las firmas de métodos, no tienen suerte, por lo que usar este estilo en una interfaz de biblioteca es probablemente una práctica realmente mala.
Me parece que escribir cosas con todos los tipos posibles implícitos en realidad hace que mi código sea mucho más fácil de seguir para mí, porque elimina casi todo el desorden habitual de C ++. Su kilometraje puede, por supuesto, variar, y eso es lo que me interesa saber. ¿Cuáles son las ventajas y desventajas específicas del uso radical de la inferencia de tipos?
fuente
Respuestas:
Siendo principalmente un programador de Python, comparto la mentalidad de que el programador no necesita saber el tipo exacto. En el caso de C ++, especialmente cuando se trata de plantillas con plantillas con plantillas ... Por supuesto, eso no se debe a que desprecie la escritura estática (no, considero que Haskell es una de las mejores cosas desde el pan rebanado, en parte debido a su escritura estática), sino porque no me importa el tipo exacto. Por qué, no se demuestra bien con ejemplos que usan nombres como
foo
oget_stuff()
. Así que escojamos algo más cercano a la realidad:No es una sola anotación de tipo, pero está perfectamente claro lo que hace, ¿verdad? Este código no le importa de qué tipo es
users
, solo necesita un rango para iterar sobre el que contiene cosas con unaname
que se puede alimentarcheck_name
. Nada mas. A nadie le importan los 100 caracteres de los nombres de tipo que de lo contrario tendría que escribir.Lo mismo se aplica a la mayoría de los códigos con nombres significativos. El ejemplo en la pregunta no es claro, pero tampoco sería claro con nombres de tipo explícitos, porque ni el contexto ni los identificadores dan ninguna indicación de lo que está sucediendo. Utilice identificadores significativos, y el código se puede entender independientemente de las anotaciones de tipo explícito.
fuente
La razón por la que hicieron inferencia fue para evitar que las personas escribieran código como:
Cuando podrías escribir:
Excepto que Foo sería un tipo de plantilla largo, por lo que se vuelve más agradable escribir:
Por lo tanto, como regla general, si usar auto hace que escriba código como se indicó anteriormente en lugar de código similar al del primer ejemplo, entonces úselo. De lo contrario, siga agregando definiciones explícitas.
fuente
auto
muchos casos en los que estoy seguro de que otros serían explícitos, pero no veo lo que realmente está mal, por ejemploauto f = new SomethingLong()
, porque es obvio lo que devuelve la expresión. Me pregunto dónde dibujar la línea.SomethingLong
no es parte de ninguna estructura de herencia, pero a menos que esté seguro de que nunca lo será, le aconsejaría que no lo haga. Es mucho más fácil trazar la línea con precaución.Hay buenas razones para no usar siempre la inferencia de tipos. Haskell tiene inferencia de tipos, pero generalmente declaro tipos de funciones explícitamente de todos modos. Eso es en parte el resultado de mi estilo de desarrollo. Declaro la función primero:
A continuación, escribiré el código que usa esa función y haré una compilación para asegurarme de que escribe verificaciones. Una vez que escriba cheques, continuaré con la implementación.La otra razón para declarar tipos de funciones es que las declaraciones pueden servir como documentación adicional. Que esta documentación se verifique en cada compilación es una ventaja.
fuente