O C ++ 0x adiciona um suporte bastante abrangente a inferência de tipos. Estou extremamente tentado a usá-lo em todos os lugares possíveis para evitar repetições indevidas, mas estou me perguntando se a remoção de informações explícitas de tipo em todo o lugar é uma boa idéia. Considere este exemplo 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);
}
Você diria que isso é razoável ou é completamente ridículo? Afinal, especialmente se você está acostumado a desenvolver em uma linguagem dinâmica, não precisa se preocupar muito com os tipos de coisas e pode confiar que o compilador detectará qualquer abuso flagrante do sistema de tipos. Mas para aqueles que dependem do suporte do editor para assinaturas de métodos, você está sem sorte; portanto, usar esse estilo em uma interface de biblioteca é provavelmente uma prática muito ruim.
Acho que escrever coisas com todos os tipos possíveis implícitos, na verdade, facilita muito o meu código, porque remove quase toda a desordem usual do C ++. Sua milhagem pode, é claro, variar, e é sobre isso que estou interessado em ouvir. Quais são as vantagens e desvantagens específicas do uso radical da inferência de tipo?
fonte
Respostas:
Sendo principalmente um programador Python, compartilho a mentalidade de que o programador não precisa saber o tipo exato. No caso de C ++, especialmente quando se lida com modelos de modelos com modelos ... É claro que isso não acontece porque detesto a digitação estática (não considero - considero Haskell uma das melhores coisas desde o pão fatiado, em parte devido à sua digitação estática), mas porque não me importo com o tipo exato. Por que, não é bem demonstrado por exemplos que usam nomes como
foo
ouget_stuff()
. Então, vamos escolher algo mais próximo da realidade:Não é uma anotação de tipo único, mas é perfeitamente claro o que faz, certo? Esse código não se importa com o tipo
users
, apenas precisa de algum intervalo para iterar sobre o que contém itens com osname
quais pode ser alimentadocheck_name
. Nada mais. Ninguém se importa com os 100-ish caracteres dos nomes de tipo que você teria que digitar de outra forma.O mesmo se aplica à maioria dos códigos com nomes significativos. O exemplo da pergunta não é claro, mas também não seria claro com nomes de tipo explícitos, porque nem o contexto nem os identificadores fornecem qualquer indicação do que está acontecendo. Use identificadores significativos e o código pode ser entendido independentemente das anotações de tipo explícitas.
fonte
A razão pela qual eles trouxeram inferência foi impedir que as pessoas escrevessem códigos como:
Quando você poderia escrever:
Exceto que Foo seria algum tipo de modelo longo, então torna-se melhor escrever:
Portanto, como regra geral, se o uso de auto faz com que você escreva o código como acima, em vez de um código semelhante ao primeiro exemplo, use-o. Caso contrário, continue adicionando definições explícitas.
fonte
auto
em muitos casos em que tenho certeza de que outros seriam explícitos, mas não vejo o que há realmente de errado, por exemploauto f = new SomethingLong()
, porque é óbvio o que a expressão retorna. Eu só estou me perguntando onde traçar a linha.SomethingLong
não fizer parte de nenhuma estrutura de herança, mas, a menos que você tenha certeza de que nunca será, aconselho isso. É muito mais fácil traçar a linha do lado cauteloso.Existem boas razões para nem sempre usar a inferência de tipo. Haskell tem inferência de tipo, mas geralmente declaro explicitamente os tipos de função. Isso é parcialmente resultado do meu estilo de desenvolvimento. Declaro a função primeiro:
Em seguida, vou escrever o código que usa essa função e fazer uma compilação para garantir que digite as verificações. Depois de digitar as verificações, irei adiante com a implementação.A outra razão para declarar tipos de função é que as declarações podem servir como documentação adicional. Que esta documentação seja verificada em todas as compilações é um bônus.
fonte