在c++中,如何找到变量的类型?
当前回答
c++和Javascript的主要区别在于c++是静态类型的语言,而Javascript是动态的。
在动态类型语言中,变量可以包含任何东西,它的类型由它所持有的值决定。 在静态类型语言中,变量的类型是声明的,并且不能改变。
可以有动态分派、对象组合和子类型(继承和虚函数),也可以有静态分派和超类型(通过模板CRTP),但在任何情况下,编译器必须知道变量的类型。
如果你不知道它是什么或可能是什么,那是因为你设计了一些东西,因为语言有一个动态类型系统。
如果是这种情况,你最好重新考虑一下你的设计,因为它将进入一个对你所使用的语言来说不自然的领域(最像和毛毛虫一起在高速公路上行驶,或者和汽车一起在水里行驶)
其他回答
我不确定我的回答是否有用。
简单的回答是,你不需要/不想知道变量的类型来使用它。
如果你需要给一个静态变量一个类型,那么你可以简单地使用auto。
在更复杂的情况下,你想在类或结构中使用“auto”,我建议使用template with 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<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()的有效用例,与使用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
}
通常,想要在c++中找到变量的类型是一个错误的问题。它往往是从过程性语言(例如C或Pascal)中继承下来的。
如果你想根据类型编写不同的行为,试着学习例如函数重载和对象继承。在你学习c++的第一天,这不会马上有意义,但请坚持下去。
c++和Javascript的主要区别在于c++是静态类型的语言,而Javascript是动态的。
在动态类型语言中,变量可以包含任何东西,它的类型由它所持有的值决定。 在静态类型语言中,变量的类型是声明的,并且不能改变。
可以有动态分派、对象组合和子类型(继承和虚函数),也可以有静态分派和超类型(通过模板CRTP),但在任何情况下,编译器必须知道变量的类型。
如果你不知道它是什么或可能是什么,那是因为你设计了一些东西,因为语言有一个动态类型系统。
如果是这种情况,你最好重新考虑一下你的设计,因为它将进入一个对你所使用的语言来说不自然的领域(最像和毛毛虫一起在高速公路上行驶,或者和汽车一起在水里行驶)
推荐文章
- 在Visual Studio中默认从项目中删除安全警告(_CRT_SECURE_NO_WARNINGS)
- auto&&告诉我们什么?
- 我如何调用::std::make_shared类只有保护或私有构造函数?
- 你不应继承std::vector
- 访问越界的数组不会出现错误,为什么?
- c++结构体的成员默认初始化为0吗?
- 有没有办法在Java中模拟c++的“朋友”概念?
- 什么是string_view?
- 有什么更好的方法来避免do-while(0);精通c++ ?
- 我可以在C或c++中使用二进制文字吗?
- c++中嵌套类型/类的前向声明
- c++ STL向量:从索引获取迭代器?
- 如何“=默认”不同于“{}”默认构造函数和析构函数?
- 如何把一个字符串分成多个变量在bash shell?
- 面试问题:检查一个字符串是否是另一个字符串的旋转