繁体   English   中英

运行时确定C ++的类型

[英]runtime determine type for C++

我想知道是否可以将类型确定为C ++中的运行时信息。

(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;  
 }

对于此示例,有两个问题:

(a)“argv [1] to t”是错误的,但C字符串argv [1]中的类型信息是否可以转换为实际的类型关键字? 所以我们不需要通过if-else子句和strcmp检查每种类型。

(b)如何在if子句的局部范围内定义的变量t仍在外部有效。 即如何将局部变量“导出”到其范围之外?

(2)一般来说,不是特定于上面的简单示例,运行时确定类型的常用方法是什么? 在我看来,可能有一些方法:

(a)可以将类型定义的变量的处理放在同一范围内定义。 例如

 #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;  
 }

并且可能使用模板函数使各种类型的公共代码可重用。

(b)或者可以使用抽象类类型和多态来间接导出定义,但我不确定如何。

谢谢你的建议!

1a:不,类型不是C ++中的对象或值(例如,在Python中)。 但是,您可以使用由argv [1]的值选择的各种值。

1b:对不起,就是不能那样做。

2:dynamic_cast和typeid(两个运算符)是当前由查询类型的语言提供的唯一工具(并不罕见,大多数语言都有很少但专用的工具),并且通常不鼓励使用它们来查询类型关于情况(在其他语言中也不常见)。

2a:是的,因为这是简单的,显而易见的,并且在这里工作 - 没有理由使用其他任何东西,但是因为它是示例代码,我们假设您需要一个不同的解决方案。 您可以调用在正确类型上实例化的函数模板,但由于这与2a的其余部分几乎相同,所以我不会进入它。

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;
  }
};

使用:

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;
}

这开始将两种类型合并为一种类型,它们在这里都呈现相同的接口Base。 然而,这并不适用于每个解决方案,并且诸如boost.variant之类的变体可以更好,特别是当所需的各种类型数量少且事先已知时。

您需要一个能够存储不同类型值的类。 如果没有工会, Boost的变体类将是正确的选择。

查看Boost.Variant

暂无
暂无

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

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