运行时确定C ++的类型 [英] runtime determine type for C++

查看:103
本文介绍了运行时确定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; //错误:'t'未在此范围中声明
return 0;
}

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



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



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



(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 = 2;
cout<< t < endl;
} else if(strcmp(argv [1],float)== 0)
{
float t = 2.2;
cout<< t < endl;
}
return 0;
}

并且可能使用模板函数使各种类型的通用代码可重用。 / p>

(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值:Base {
T data;
explicit
value(T const& data):data(data){}
private:
virtual void _print(std :: ostream& s)const {
s <<数据;
}
};

使用:

 code> 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 < '\\\
';
return 0;
}

这开始将两种类型合并为一种类型,相同的接口,Base,这里。但是,这不适合每个解决方案,并且一个变体,如 boost.variant 可以更好,特别是当需要的各种类型数量很少,并提前知道。


I am wondering if type can be determined as runtime information in C++.

(1) Although my question is quite general, for simplicity, I will start from a simple example:

 #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? So we don't need to check for every type by if-else clause and strcmp.

(b) how to make variable t defined inside the local scope of the if clause still valid outside. i.e 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? 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. e.g.

 #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.

Thanks for your advice!

解决方案

1a: No, types are not objects or values in C++ (as they are, for example, in Python). You can, however, use various values selected by the value of argv[1].

1b: Sorry, just can't do that.

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).

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. 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.

2b: Example using a subclass template, just because it's handy:

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. 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.

这篇关于运行时确定C ++的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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