Ответ 1
struct empty_type {};
using cell_type = boost::variant<std::string, double, empty_type>;
Затем вы сделаете что-то с ячейкой с помощью:
boost::apply_visitor(some_visitor(), cell);
Предположим, например, что вы хотите реализовать электронную таблицу на С++. Ячейкой может быть строка, число или, возможно, пустое. Игнорируйте другие случаи, например, формулу.
В Haskell вы можете сделать что-то вроде:
data Cell = CellStr String | CellDbl Double | None
Что считается текущей "лучшей практикой" для этого в С++? Использовать объединение в структуре с индикатором типа или что-то еще?
struct empty_type {};
using cell_type = boost::variant<std::string, double, empty_type>;
Затем вы сделаете что-то с ячейкой с помощью:
boost::apply_visitor(some_visitor(), cell);
Наследование?
Я должен сказать, что мне не очень нравится этот метод и не будет считать его современным, но он по-прежнему кажется стандартным.
class DoubleCell : public Cell {
double value;
public:
DoubleCell( double v ) : value(v) {}
double DoubleValue() { return value; }
...
};
class StringCell : public Cell {
std::string value;
public:
StringCell( std::string v ) : value(v) {}
std::string StringValue() { return value; }
...
};
class EmptyCell : public Cell {
...
};
Некоторые из недостатков:
При получении фактического значения вам нужно использовать разные функции. Обычно это связано с использованием instanceof
и литья.
Различные объекты нельзя напрямую помещать в контейнер, только как указатели.
Стандартный способ реализации полиморфизма - это виртуальные классы. http://www.cplusplus.com/doc/tutorial/polymorphism/
Это базовый механизм С++.