如何检查C ++中的数据类型? [英] How to check data type in C++?

查看:126
本文介绍了如何检查C ++中的数据类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C ++相当陌生,我主要使用python.我正在尝试检查存储在我正在处理的对象中的值的变量类型.我记得在Python中有一个命令号isinstance,我可以用它作为条件来运行某些命令,例如如果下一个值是字符串,则执行A,如果它是int则执行B.

I'm fairly new to C++, I've been mainly using python. I'm trying to check the type of variable of the value stored in the objects I'm working on. I remember that in Python there was a comand isinstance where I could use it as a condition to run certain commands, like if the next value is a string, do A, and if it's an int do B.

有没有一种方法可以快速检查C ++中变量的数据类型?

Is there a way to quickly check what's the data type on a variable in C++?

示例:

在python中,我有一个带有数学运算的数组,每个字符在一个字段中

In python I had an array with a math operation, each character in a field

[3,"+",2]

当我读取数组时,我会使用isinstance命令将整数与字符串分开

as I read the array I would separate the ints from the strings with the isinstance command

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 ++中,我需要做类似的事情,但是这次每个字符都在链表中的一个节点中,再次,我需要将它们,链表中的整数和另一个链表中的字符串分开

now in C++ I need to do something similar, but this time each character is in a node from a linked list and again, I need to separate them, ints in a linked list, and strings in another linked list

推荐答案

您似乎正在苦苦挣扎的是C ++是静态的(相对)强类型的语言.对于每个术语实际上意味着什么的讨论,我指的是另一个问题,因为在那里解释可能比这里的要好得多.我可以.

What you seem to be struggling with is that C++ is a statically and a (relatively) strongly typed language. For a discussion about what each of these terms actually mean i refer to this other question, as it's explained there probably much better than I could.

首先,您应该确定自己确实需要按照当前尝试的方式进行操作.不要尝试编写Python样式代码.

First of all you should be sure that you actually need to do things the way you're trying currently. Do not try to write Python style code.

也就是说,基本上可以使用两种不同的方法来实现与Python(动态类型,鸭子类型以及相对弱类型)所允许的行为类似的行为:

That said, there are basically two different approaches with which you can achieve a behavior that's similar to what Python (dynamically typed, duck typing and thus relatively weak typing) allows you to do:

  1. 使用C ++的内置动态类型机制.因此,您需要创建一个所谓的 polymorphic基类,该基类至少具有一个虚拟成员函数(如果您没有定义的接口,则析构函数也可以工作-它通常是并且必须是虚拟的,以避免出现令人讨厌的问题).一个简短的例子:

  1. Use C++'s builtin dynamic type mechanisms. Therefore, you need to create a so called polymorphic base class, that is a class that has at least one virtual member function (the destructor also works if you don't have a defined interface - it most often also must be virtual to avoid nasty issues). A short example:

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的实际类型,让用户决定:

Using this you can now for example store Values whose actual type you can let the user decide:

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向量)使用指针.

This is easily extensible to more types. Note that in order to use C++'s builtin dynamic typing you need to go without value semantics, but instead completely use reference semantics, either using real references, or (in most cases where ownership must be transferred, like in above example to the values vector) using pointers.

dynamic_cast方法的工作原理与此非常相似,不同之处在于,您可以更明确地使用运行时类型信息,并且不需要统一的接口(但需要做更多的工作来维护代码).

The dynamic_cast approach works very similar to this, except that you're using runtime type information more explicitly and don't need a unified interface (but have much more work in order to maintain your code).

使用union语言功能.只有在C ++ 11中,这才真正成为可能,其中工会成员可能是不可理解的:

Use the union language feature. This only has become really possible with C++11, where union members may be non-trivially construable:

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,您将浪费一些内存.

As you can see, this quite a lot of work. With this approach you can use value semantics, but cannot as easily extend your Values to support more types. Moreover, due to using a union, you're going to waste some memory.

底线:您需要自己实现行为,但是可以完全按照您希望的行为方式来实现.例如:您还可以实现进行隐式类型转换的赋值运算符operator=(Value const &).您还可以使用 boost 中的实现,例如boost::anyboost::variant.

Bottom line: You need to implement the behavior on your own, but can do so in exactly the way you want it to behave. For example: You could also implement assignment operators operator=(Value const &) that do implicit type conversions. You can also use the implementations from boost, like boost::any or boost::variant.

我想参考我在本网站上写的关于同一主题的两个答案,也许它们对您也有帮助:

I'd like to reference two answers I've written on this site to the very same subject, perhaps they're also helpful for you:

  • https://stackoverflow.com/a/32926607/1116364
  • https://stackoverflow.com/a/32041381/1116364

还有一些相关的C代码,因为它试图解决相同的问题: https://stackoverflow.com/a/35443434/1116364

Also some C code which is relevant, because it tries to solve the same issue: https://stackoverflow.com/a/35443434/1116364

注意:此答案中的所有代码都是直接从内存中写入的,未经测试.因此,它仅用作基本技术的演示.

这篇关于如何检查C ++中的数据类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆