简体   繁体   English

运行时确定C ++的类型

[英]runtime determine type for C++

I am wondering if type can be determined as runtime information in C++. 我想知道是否可以将类型确定为C ++中的运行时信息。

(1) Although my question is quite general, for simplicity, I will start from a simple example: (1)虽然我的问题很笼统,但为简单起见,我将从一个简单的例子开始:

 #include <stdio.h>  
 #include <iostream>  
 #include <cstring>  
 using namespace std;  
 int main(int argc, char * argv[])  
 {  
 if (strcmp(argv[1], "int")==0)   
 {  
     int t = 2;   
 }else if (strcmp(argv[1], "float")==0)  
 {  
     float t = 2.2; 
 } 
 cout << t << endl;  // error: ‘t’ was not declared in this scope
 return 0;  
 }

For this example, there are two questions: 对于此示例,有两个问题:

(a) "argv[1] to t" is wrong, but can the type info in the C string argv[1] be converted to the actual type keyword? (a)“argv [1] to t”是错误的,但C字符串argv [1]中的类型信息是否可以转换为实际的类型关键字? So we don't need to check for every type by if-else clause and strcmp. 所以我们不需要通过if-else子句和strcmp检查每种类型。

(b) how to make variable t defined inside the local scope of the if clause still valid outside. (b)如何在if子句的局部范围内定义的变量t仍在外部有效。 ie how to "export" a local variable to the outside of its scope? 即如何将局部变量“导出”到其范围之外?

(2) Generally speaking, not specific to the simple example above, what are the usual ways to runtime determine types? (2)一般来说,不是特定于上面的简单示例,运行时确定类型的常用方法是什么? It seems to me that there might be some ways: 在我看来,可能有一些方法:

(a) one can put the processing of the variable defined from the type inside the same scope its definition. (a)可以将类型定义的变量的处理放在同一范围内定义。 eg 例如

 #include <stdio.h>  
 #include <iostream>  
 #include <cstring>  
 using namespace std;  
 int main(int argc, char * argv[])  
 {  
 if (strcmp(argv[1], "int")==0)   
 {  
     int t = 2;   
     cout << t << endl; 
 }else if (strcmp(argv[1], "float")==0)  
 {  
     float t = 2.2; 
     cout << t << endl; 
 } 
 return 0;  
 }

And possibly use template function to make the common code for various types reusable. 并且可能使用模板函数使各种类型的公共代码可重用。

(b) or one may use abstract class type and polymorphism to indirectly export the definition out, but I am not sure how exactly. (b)或者可以使用抽象类类型和多态来间接导出定义,但我不确定如何。

Thanks for your advice! 谢谢你的建议!

1a: No, types are not objects or values in C++ (as they are, for example, in Python). 1a:不,类型不是C ++中的对象或值(例如,在Python中)。 You can, however, use various values selected by the value of argv[1]. 但是,您可以使用由argv [1]的值选择的各种值。

1b: Sorry, just can't do that. 1b:对不起,就是不能那样做。

2: dynamic_cast and typeid (both operators) are the only tools currently provided by the language to query type (not unusual, most languages have very few, but dedicated, tools for that), and using them solely to query type is often discouraged depending on situation (also not unusual among other languages). 2:dynamic_cast和typeid(两个运算符)是当前由查询类型的语言提供的唯一工具(并不罕见,大多数语言都有很少但专用的工具),并且通常不鼓励使用它们来查询类型关于情况(在其他语言中也不常见)。

2a: Yes, and as that is the simple, obvious, and works here—there's no reason to use anything else, but as it's example code, let's assume you need a different solution. 2a:是的,因为这是简单的,显而易见的,并且在这里工作 - 没有理由使用其他任何东西,但是因为它是示例代码,我们假设您需要一个不同的解决方案。 You could call a function template instantiated on the right type, but as this is pretty much the same thing as the rest of 2a, I don't go into it. 您可以调用在正确类型上实例化的函数模板,但由于这与2a的其余部分几乎相同,所以我不会进入它。

2b: Example using a subclass template, just because it's handy: 2b:使用子类模板的示例,因为它很方便:

struct Base {
  virtual ~Base() {}
  friend std::ostream& operator<<(std::ostream& s, Base const& v) {
    v._print(s);
    return s;
  }
private:
  virtual void _print(std::ostream&) const = 0;
};

template<class T>
struct Value : Base {
  T data;
  explicit
  Value(T const& data) : data(data) {}
private:
  virtual void _print(std::ostream& s) const {
    s << data;
  }
};

Use: 使用:

int main(int argc, char** argv) {
  using namespace std;
  auto_ptr<Base> p;
  string const type = argc > 1 ? argv[1] : "int";
  if (type == "int") {
    p.reset(new Value<int>(2));
  }
  else if (type == "float") {
    p.reset(new Value<double>(2.2));
  }
  cout << *p << '\n';
  return 0;
}

This is starting to merge the two types into one type, and they both present the same interface, Base, here. 这开始将两种类型合并为一种类型,它们在这里都呈现相同的接口Base。 However, this doesn't lend itself well to every solution, and a variant such as boost.variant can be better, particularly when the various types required are small in number and known well in advance. 然而,这并不适用于每个解决方案,并且诸如boost.variant之类的变体可以更好,特别是当所需的各种类型数量少且事先已知时。

You need a class that's capable of storing a value of different types. 您需要一个能够存储不同类型值的类。 Short from a union, Boost's variant class would be the proper choice. 如果没有工会, Boost的变体类将是正确的选择。

查看Boost.Variant

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM