Em C ++, como se encontra o tipo de uma variável?
Em C ++, como se encontra o tipo de uma variável?
Respostas:
Você pode usar o operador typeid :
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
significa número inteiro no seu compilador. Os nomes retornados não são especificados pelo padrão.
typeid
são muito abreviados, específicos do compilador e não se destinam ao consumo humano. Você pode "desmontá-las" (esse é o termo real!), Em código com algo como gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html , com utilitários de linha de comando, como c++filt
com qualquer um dos vários desmanglers online como demangler.com .
Se você tem uma variável
int k;
Você pode obter esse tipo usando
cout << typeid(k).name() << endl;
Veja o seguinte tópico no SO: Pergunta semelhante
A principal diferença entre C ++ e Javascript é que C ++ é uma linguagem de tipo estático, enquanto o javascript é dinâmico.
Nas linguagens dinâmicas digitadas, uma variável pode conter qualquer coisa, e seu tipo é dado pelo valor que mantém, momento a momento. Nos idiomas estáticos, o tipo de uma variável é declarado e não pode ser alterado.
Pode haver despacho dinâmico e composição e subtipagem de objetos (herança e funções virtuais), bem como despacho estático e supertipagem (via modelo CRTP), mas, em qualquer caso, o tipo da variável deve ser conhecido pelo compilador.
Se você está em posição de não saber o que é ou poderia ser, é porque você projetou algo como a linguagem tem um sistema de tipos dinâmico.
Se for esse o caso, é melhor repensar o seu design, pois ele está indo para um terreno não natural para o idioma que você está usando (mais como ir em uma estrada com uma lagarta ou na água com um carro)
Geralmente, querer encontrar o tipo de uma variável em C ++ é a pergunta errada. Tende a ser algo que você carrega de linguagens procedurais como, por exemplo, C ou Pascal.
Se você deseja codificar comportamentos diferentes, dependendo do tipo, tente aprender, por exemplo , sobrecarga de funções e herança de objetos . Isso não fará sentido imediato no seu primeiro dia de C ++, mas continue assim.
Acredito que tenho um caso de uso válido para usar typeid (), da mesma forma que é válido usar sizeof (). Para uma função de modelo, preciso especificar um caso especial do código com base na variável de modelo, para oferecer a máxima funcionalidade e flexibilidade.
É muito mais compacto e sustentável do que usar polimorfismo, criar uma instância da função para cada tipo suportado. Mesmo nesse caso, eu poderia usar esse truque para escrever o corpo da função apenas uma vez:
Observe que, como o código usa modelos, a instrução switch abaixo deve ser resolvida estaticamente em apenas um bloco de código, otimizando todos os casos falsos, AFAIK.
Considere este exemplo, onde podemos precisar manipular uma conversão se T for um tipo versus outro. Eu o uso para a especialização de classe para acessar o hardware em que o hardware usará o tipo myClassA ou myClassB. Em uma incompatibilidade, preciso gastar tempo convertendo os dados.
switch ((typeid(T)) {
case typeid(myClassA):
// handle that case
break;
case typeid(myClassB):
// handle that case
break;
case typeid(uint32_t):
// handle that case
break;
default:
// handle that case
}
typeid
simplesmente não pode ser uma verificação estática em tempo de compilação - por definição -, portanto, isso não facilita nenhuma otimização. For a template function, I need to special case the code based on the template variable
Certo, então o que você realmente deseja é polimorfismo estático através do idioma CRTP. É exatamente o que isso alcança.
Não tenho certeza se minha resposta ajudaria.
A resposta curta é que você realmente não precisa / deseja saber o tipo de variável para usá-la.
Se você precisar atribuir um tipo a uma variável estática, basta usar auto.
No caso mais sofisticado em que você deseja usar "auto" em uma classe ou estrutura, sugiro usar o modelo com decltype.
Por exemplo, digamos que você esteja usando a biblioteca de outra pessoa e ela possua uma variável chamada "unknown_var" e deseje colocá-la em um vetor ou estrutura, você pode fazer isso totalmente:
template <typename T>
struct my_struct {
int some_field;
T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector
Espero que isto ajude.
EDIT: Para uma boa medida, aqui está o caso mais complexo que consigo pensar: ter uma variável global de tipo desconhecido. Nesse caso, você precisaria de c ++ 14 e variável de modelo.
Algo assim:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
Ainda é um pouco tedioso, mas é o mais próximo possível dos idiomas sem fonte. Apenas certifique-se sempre que você referenciar a variável do modelo, sempre coloque a especificação do modelo lá.
Se você precisar fazer uma comparação entre uma classe e um tipo conhecido, por exemplo:
class Example{};
...
Example eg = Example();
Você pode usar esta linha de comparação:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
que verifica se o typeid
nome contém o tipo de string (o nome typeid possui outros dados desconfigurados, é melhor fazer isso em s1.find(s2)
vez de ==
).
Você pode definitivamente ir para typeid(x).name()
onde x é o nome da variável. Na verdade, ele retorna um ponteiro const char para o tipo de dados. Agora, observe o seguinte código.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 36;
char c = 'A';
double d = 1.2;
if(*(typeid(n).name()) == 'i'){
cout << "I am an Integer variable" << endl;
}
if(*((char *) typeid(d).name()) == 'd'){
cout << "I am a Double variable" << endl;
}
if(*((char *) typeid(c).name()) == 'c'){
cout << "I am a Char variable" << endl;
}
return 0;
}
Observe como primeiro e segundo os dois se funcionam.
std::cout << "I'm a variable of type " << typeid(n).name()
. (reformulado para impedir artefatos a / an, mas isso pode ser corrigido com outra verificação). Mesmo assim, se você absolutamente deseja uma comparação, é muito melhor fazer issotypeid(n) == typeid(int)