在C ++中,如何找到变量的类型?
在C ++中,如何找到变量的类型?
Answers:
您可以使用typeid运算符:
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
意味着编译器上的整数。返回的名称不是由标准指定的。
typeid
非常缩写,特定于编译器,并不供人类使用。您可以使用诸如gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html之类的代码在代码中使用“ demangle”它们(这是实际术语!),使用诸如的命令行实用程序c++filt
或使用各种在线demanglers中的任何一个如demangler.com。
C ++和Javascript之间的主要区别在于C ++是一种静态类型的语言,而javascript是动态的。
在动态类型语言中,变量可以包含任何东西,其类型由其持有的值随时提供。在静态类型语言中,变量的类型是声明的,并且不能更改。
可以有动态分派,对象组成和子类型化(继承和虚拟函数),以及静态分派和超类型化(通过模板CRTP),但是在任何情况下,编译器都必须知道变量的类型。
如果您不知道它是什么或者可能是什么,那是因为您设计了某种东西,因为该语言具有动态类型系统。
如果是这种情况,您最好重新考虑一下设计,因为它进入的语言对您而言并不自然(最像是骑着毛毛虫在高速公路上,或者是坐汽车在水中)
通常,想要在C ++中找到变量的类型是一个错误的问题。它往往是您从过程语言(例如C或Pascal)中获得的东西。
如果要根据类型编写不同的行为代码,请尝试了解有关函数重载和对象继承的信息。在您使用C ++的第一天,这不会立即生效,但请继续努力。
我相信我有一个使用typeid()的有效用例,就像使用sizeof()一样有效。对于模板功能,我需要对基于模板变量的代码进行特殊处理,以便提供最大的功能和灵活性。
与使用多态性相比,它为每种支持的类型创建一个函数实例比使用多态性更为紧凑和可维护。即使在那种情况下,我也可能使用此技巧只编写一次函数主体:
请注意,由于代码使用模板,因此以下switch语句应静态地解析为一个代码块,从而优化了所有错误情况AFAIK。
考虑这个例子,如果T是一种类型而不是另一种类型,我们可能需要处理转换。我使用它进行类专业化访问硬件,其中硬件将使用myClassA或myClassB类型。如果不匹配,我需要花时间转换数据。
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
根据定义,它根本不能是静态的编译时检查,因此这不利于任何优化。For a template function, I need to special case the code based on the template variable
是的,所以您真正想要的是通过CRTP习惯用法实现的静态多态性。这正是实现的目标。
我不确定我的回答是否会有所帮助。
简短的答案是,您实际上并不需要/不想知道使用变量的类型。
如果您需要为静态变量指定类型,则可以简单地使用auto。
在更复杂的情况下,如果您想在类或结构中使用“自动”,我建议使用带decltype的模板。
例如,假设您正在使用其他人的库,并且该库具有一个名为“ unknown_var”的变量,并且希望将其放入向量或结构中,则可以完全这样做:
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
希望这可以帮助。
编辑:好的措施,这是我能想到的最复杂的情况:具有未知类型的全局变量。在这种情况下,您将需要c ++ 14和template变量。
像这样:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
它仍然有些乏味,但与无类型语言一样近。只要确保每当您引用模板变量时,就始终将模板规范放在此处。
如果需要在类和已知类型之间进行比较,例如:
class Example{};
...
Example eg = Example();
您可以使用以下比较行:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
该命令检查typeid
名称是否包含字符串类型(typeid名称包含其他损坏的数据,因此最好使用s1.find(s2)
代替==
)。
您绝对可以在typeid(x).name()
其中x是变量名的地方使用。实际上,它返回一个指向数据类型的const char指针。现在,看下面的代码。
#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;
}
请注意,如果两者都有效,那么第一和第二如何工作。
std::cout << "I'm a variable of type " << typeid(n).name()
。(改写以防止出现伪影,但可以通过其他检查来解决)。即使这样,如果您绝对希望进行比较,那就更好了typeid(n) == typeid(int)