2015-10-03 2 views
0

Я пытаюсь написать простую программу на C++, которая создает связанный список. Я хотел бы, чтобы этот список мог хранить любые данные в своем контейнере. Тем не менее, я понял, что моя главная проблема заключается в том, чтобы принять любой тип ввода и сохранить его. Например, если переменная std::cin хранит в строке типа, будут приняты только строки, и эта переменная должна быть определена до компиляции программы.Принять и идентифицировать вход любого типа C++

Мой вопрос: есть ли способ принять любые типы ввода с помощью std::cin (или любого другого метода ввода), а затем вызвать определенные функции в зависимости от типа ввода?

Что-то по логике ...

cin >> data 

if (data.type == string) 
{ 
    cout << "data's type: string" 
} 

if (data.type == int) 
{ 
    cout << "data's type: int" 
} 

Спасибо!

+0

Возможный дубликат [C++ Variant] (http://stackoverflow.com/questions/208959/c-variant) –

+0

Прочитайте в виде строки, попробуйте преобразовать в целое число, если оно выполнено успешно (и вся строка была потребляется в преобразовании), тогда у вас было целое число, иначе это строка. Я ответил на это некоторое время назад, но, похоже, не могу найти свой собственный ответ для дубликата. –

+0

Перегрузка функции для разных типов. Почему бы не попробовать? Просто имейте тело каждой перегрузки, распечатывая каждый тип, который присваивается функции. – TimLayne

ответ

1

C++ есть (в основном) статически напечатано. То есть типы переменных должны быть известны во время компиляции и не могут изменяться во время выполнения, например. в зависимости от ввода пользователем.

Единственным исключением из этого правила являются полиморфные классы: если у вас есть базовый класс с некоторой функцией-членом virtual, тогда будет способ (скорее всего, указатель как член всех экземпляров этого класса), чтобы различать суб-классы этого класса (и себя):

struct Base { 
    virtual ~Base() {} 
}; 
struct SubA : public Base {}; 
struct SubB : public Base {}; 

// ... 

Base const & instance = SubA{}; 
try { 
    SubA const & as_subA = dynamic_cast<SubA const &>(instance); 
    // The instance is a SubA, so the code following here will be run. 
} catch (std::bad_cast const &) { /* handle that somehow */ } 

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

C++ является гибким языком, вы можете - конечно - и реализовать что-то подобное по своему усмотрению:

struct Thing { 
    enum class Type { 
    Integer, String, Vector 
    } type; 
    union { 
    int integer; 
    std::string string; 
    std::vector<int> vector; 
    } data; 
    // Plus a lot of work in constructors, destructor and assignment, see rule of 5 
}; 

Используя что-то вроде этого позволяет иметь объекты с «типа» динамической природы, и могут делать разные вещи в зависимости от того, какой тип объекта на самом деле имеет во время выполнения.

Но, конечно, вам не нужно писать это самостоятельно (though its not that hard), существует множество реализаций, например, boost::any и boost::variant.

Смежные вопросы