簡體   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