Eu estou querendo saber qual é a diferença entre typeid
e typeof
em C ++. Aqui está o que eu sei:
typeid
é mencionado na documentação para type_info, que é definida no arquivo de cabeçalho do C ++, typeinfo .typeof
é definido na extensão GCC para C e na biblioteca C ++ Boost .
Além disso, aqui está o teste do código de teste que eu criei onde descobri que typeid
não retorna o que eu esperava. Por quê?
main.cpp
#include <iostream>
#include <typeinfo> //for 'typeid' to work
class Person {
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person {
// ... Employee members ...
};
int main () {
Person person;
Employee employee;
Person *ptr = &employee;
int t = 3;
std::cout << typeid(t).name() << std::endl;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer
// to a polymorphic class)
}
resultado:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
name()
é definida pela implementação. Ele não precisa ser um nome de identificador C ++ válido, apenas algo que identifique exclusivamente o tipo. Parece que sua implementação usa o esquema geral de separação de nomes do compilador.Respostas:
A linguagem C ++ não possui tal coisa
typeof
. Você deve estar olhando para alguma extensão específica do compilador. Se você está falando sobre GCCstypeof
, um recurso semelhante está presente no C ++ 11 por meio da palavra-chavedecltype
. Novamente, o C ++ não tem taltypeof
palavra-chave.typeid
é um operador de linguagem C ++ que retorna informações de identificação de tipo em tempo de execução. Ele basicamente retorna umtype_info
objeto que é comparável à igualdade com outrostype_info
objetos.Observe que a única propriedade definida do
type_info
objeto retornado é ser comparável entre igualdade e não-igualdade, ou seja,type_info
objetos que descrevem tipos diferentes devem comparar diferentes, enquantotype_info
objetos que descrevem o mesmo tipo precisam comparar iguais. Tudo o resto é definido pela implementação. Os métodos que retornam vários "nomes" não têm garantia de retornar nada legível por humanos e nem mesmo garantem que retornem nada.Observe também que o acima provavelmente implica (embora o padrão não pareça mencioná-lo explicitamente) que aplicativos consecutivos
typeid
do mesmo tipo possam retornartype_info
objetos diferentes (que, é claro, ainda precisam ser comparados).fonte
decltype
? Não sei ao certo qual é a política geral, mas como a pergunta está marcadaC++
, espero que se refira ao padrão mais recente. Voltar a marcar a pergunta comoC++03
também seria uma opção imho. Pessoalmente, às vezes fico bastante confuso, pois tenho que usar o preC ++ 11 no trabalho e às vezes não tenho certeza do que é verdadeiro "pre11" ou "post11".decltype
não é um substituto paratypeof
.typeof
funciona em tipos também, enquantodecltype
não. Por exemplo,typeof(int)
éint
enquantodecltype(int)
é um erro.type_info
objetos que descrevem tipos diferentes devem comparar diferentes" . Na verdade, isso não é garantido . O operador de desigualdade foi removido no C ++ 20 para (presumo) desencorajar a dependência de tipos diferentes comparando não-iguais. Mas se você pensar bem, a igualdade não é segura se a desigualdade não é segura.A principal diferença entre os dois é a seguinte
Tipo de referência: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
Referência typeid: https://en.wikipedia.org/wiki/Typeid
fonte
typeid
pode operar em tempo de execução e retornar um objeto que descreve o tipo de tempo de execução do objeto, que deve ser um ponteiro para um objeto de uma classe com métodos virtuais para que o RTTI (informações sobre o tipo de tempo de execução) seja armazenado na classe. Também pode fornecer o tipo de tempo de compilação de uma expressão ou nome de tipo, se não for fornecido um ponteiro para uma classe com informações do tipo em tempo de execução.typeof
é uma extensão GNU e fornece o tipo de qualquer expressão em tempo de compilação. Isso pode ser útil, por exemplo, na declaração de variáveis temporárias em macros que podem ser usadas em vários tipos. Em C ++, você normalmente usaria modelos .fonte
typeid
aceitará qualquer expressão, não apenas aquelas que avaliam objetos com métodos virtuais. Além disso,typeid
aceitará um nome de tipo , não apenas uma expressão. Você pode dizertypeid(5)
outypeid(std::string)
se quiser.typeid
pode retornar informações do tipo em tempo de execução, se disponível, mas fornecerá informações do tipo em tempo de compilação para qualquer outra coisa.Respondendo à pergunta adicional:
Não há nada errado. O que você vê é a representação em cadeia do nome do tipo. O C ++ padrão não força os compiladores a emitirem o nome exato da classe, cabe apenas ao implementador (fornecedor do compilador) decidir o que é adequado. Em resumo, os nomes são do compilador.
Essas são duas ferramentas diferentes.
typeof
retorna o tipo de uma expressão, mas não é padrão. No C ++ 0x, existe algo chamadodecltype
que faz o mesmo trabalho AFAIK.Considerando que
typeid
é usado com tipos polimórficos. Por exemplo, digamos quecat
derivaanimal
:fonte
typeid fornece o tipo de dados em tempo de execução, quando solicitado. Typedef é uma construção de tempo de compilação que define um novo tipo conforme declarado depois disso. Não há typeof no C ++ Output aparece como (mostrado como comentários inscritos):
fonte
Você pode usar o Boost demangle para obter um nome bonito:
e algo como
fonte