время выполнения определяет тип для 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] к t" является неправильным, но может информация о типе в струне до argv [1] быть преобразованной в фактическое ключевое слово типа? Таким образом, мы не должны проверять на каждый тип если-выражением-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 t = 2;   
     cout << t << endl; 
 }else if (strcmp(argv[1], "float")==0)  
 {  
     float t = 2.2; 
     cout << t << endl; 
 } 
 return 0;  
 }

И возможно используйте шаблонную функцию для создания общего кода для различных типов допускающим повторное использование.

(b) или можно использовать тип абстрактного класса и полиморфизм для косвенного экспорта определения, но я не уверен как точно.

Спасибо за Ваш совет!

5
задан Tim 31 December 2009 в 08:14
поделиться

3 ответа

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

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

Это начинает объединять два типа в один тип, и оба они представляют один и тот же интерфейс, Базовый, здесь. Однако, это не подходит для каждого решения, и такой вариант, как boost.variant может быть лучше, особенно, когда требуемые различные типы малочисленны и известны заранее.

8
ответ дан 18 December 2019 в 11:57
поделиться

Вам нужен класс, который способен хранить значения различных типов. Коротко от объединения, будет правильным выбором вариант класса Boost.

.
5
ответ дан 18 December 2019 в 11:57
поделиться

Проверьте Boost.Variant.

.
2
ответ дан 18 December 2019 в 11:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: