如何在C++中检查数据类型
How to check data type in C++?
我对C++相当陌生,我一直在使用python。我正在尝试检查存储在我正在处理的对象中的值的变量类型。我记得在 Python 中有一个 comand isinstance
我可以使用它作为运行某些命令的条件,例如如果下一个值是字符串,则执行 A,如果它是 int do B。
有没有办法快速检查C++变量的数据类型?
例:
在python中,我有一个带有数学运算的数组,每个字符都在一个字段中
[3,"+",2]
当我读取数组时,我会使用 isinstance 命令将整数与字符串分开
if isinstance(list[0],int):
aux1.append(list[0])
list=list[1:]
else:
if isinstance(lista[0],str):
aux2.append(list[0
list=list[1:]
现在在C++我需要做类似的事情,但是这次每个字符都在链表的节点中,同样,我需要将它们分开,链表中的整数和另一个链表中的字符串
您似乎正在努力解决的是C++是一种静态和(相对)强类型的语言。为了讨论这些术语中的每一个实际上意味着什么,我指的是另一个问题,因为它在那里的解释可能比我能做的要好得多。
首先,你应该确保你确实需要按照你目前尝试的方式做事。不要尝试编写 Python 风格的代码。
也就是说,基本上有两种不同的方法可以实现类似于 Python 的行为(动态类型、鸭子类型以及因此相对弱的类型)允许您执行的行为:
-
使用 C++ 的内置动态类型机制。因此,您需要创建一个所谓的多态基类,即具有至少一个虚拟成员函数的类(如果您没有定义的接口,析构函数也可以工作 - 它通常也必须是虚拟的以避免令人讨厌的问题)。举个小例子:
struct Value { virtual void write_to(std::ostream &) const = 0; virtual void read_from(std::istream &) = 0; virtual ~Value() {} // Absolutely required!!! }; struct Number : public Value { int data; void write_to(std::ostream & stream) const { stream << "<Number " << data << ">"; } void read_from(std::istream & stream) { stream >> data; // Not the same format as write_to, shame on me } // Implicit destructor is fine }; struct String : public Value { std::string data; void write_to(std::ostream & stream) const { stream << "<String " << data.size() << " " << data << ">"; } void read_from(std::istream & stream) { stream >> data; // Not the same format as write_to, shame on me } };
例如,使用它,您现在可以存储其实际类型的
Value
,您可以让用户决定:std::vector<std::unique_ptr<Value>> values; while (wantsToEnterMoreValues) { std::string choice = ask("What type of value do you want to enter?"); std::unique_ptr<Value> value; if (choice == "string") { value = std::make_unique<String>(); } else if (choice == "number") { value = std::make_unique<Number>(); } else { // launch apocalypse } value->read_from(std::cin); values.push_back(value); }
这很容易扩展到更多类型。请注意,为了使用C++的内置动态类型,您需要不使用值语义,而是完全使用引用语义,要么使用实际引用,要么(在大多数情况下必须转移所有权,如上例到
values
向量)使用指针。dynamic_cast
方法的工作方式与此非常相似,不同之处在于您更明确地使用运行时类型信息,并且不需要统一的接口(但为了维护代码而需要做更多的工作)。 -
使用
union
语言功能。这只有在C++11中才真正成为可能,工会成员可能不平凡地解释:enum class Type { Number, String }; struct Value { Type type; union { std::string string; int number; }; Value(std::string const & s) : type(Type::String), string(s) {} Value(int n) : type(Type::Number), number(n) {} Value(Value const & v) : type(v.type) { switch (type) { case Type::Number: number = v.number; break; case Type::String: new (&string) std::string(v.string); break; default: break; // Launch nuclear missiles } } ~Value() { switch (type) { case Type::String: string.~std::string(); break; default: break; } } };
如您所见,这需要做很多工作。使用此方法,可以使用值语义,但不能轻松地扩展
Value
以支持更多类型。此外,由于使用union
,您将浪费一些内存。
底线:您需要自己实现行为,但可以完全按照您希望它的行为方式实现。例如:还可以实现执行隐式类型转换的赋值运算符operator=(Value const &)
。您还可以使用 boost 中的实现,例如 boost::any
或 boost::variant
。
我想参考我在这个网站上写的两个关于同一主题的答案,也许它们对你也有帮助:
- https://stackoverflow.com/a/32926607/1116364
- https://stackoverflow.com/a/32041381/1116364
还有一些相关的C代码,因为它试图解决同样的问题:https://stackoverflow.com/a/35443434/1116364
注意:此答案中的所有代码都是直接从内存中编写的,未经测试。因此,它仅作为基本技术的演示。
与Python不同,C++是一种强类型语言。这意味着每个对象的类型在编译时是已知的。
话虽如此,有一个非常非常模糊的类比可以在某些情况下适用。
如果指针指向其类至少具有一个虚拟方法的对象,则dynamic_cast
会将其转换为指向所请求类的指针或指向nullptr
的指针。仅当指向的最派生对象明确包含其层次结构中的两个类时,这才有效。
- 如何在 CPP 中检查给定输入的数据类型?
- C++ - 检查结构数据类型中的单词是否为回文
- BoostSpirit.Qi-针对原始数据类型进行边界检查
- 输入数据类型检查循环未按预期工作 (C++)
- 在编译时检查特征类型保存的数据在内存中是否连续
- 如何检查程序是否超过数据类型存储
- 检查模板函数的数据类型
- 如何便携式检查SuSv3数据类型的极值
- c++检查xs:double数据类型
- 有没有一种方法可以检查模板的数据类型
- 如何在C++中检查数据类型
- 如何使用 cppunit 断言宏来检查返回数据类型的预处理器值
- 如何根据 2 个枚举值检查创建具有 2 个数据类型参数C++模板类
- 检查长类型数据是否在 int 范围内的便携式方法是什么?
- 对字符串和基本数据类型应用大于或小于检查
- 是否有一种仅使用基本概念检查输入数据类型的方法
- 如何检查字符串中值的数据类型
- 如何检查数据类型是否为数组?(c++)
- 如果我将数字存储为整数数据类型,如何检查另一个数字中是否存在一个数字
- 检查int数据类型的输入是否有效