Я пишу интерпретатор на C++ для лиспоподобного языка моей скромной конструкции. Это для развлечения и обучения, поэтому я не стремлюсь к абсолютной эффективности. Но я стараюсь иметь очень чистый код на C++. Сейчас я задаюсь вопросом, как реализовать встроенные функции.
В основном, я делаю следующее :
У меня есть абстрактный базовый класс DataObject, который просто предоставляет информацию о типе (в настоящее время double, int, bool) и наследуется конкретными контейнерами данных, например :
class DataObject
{
public:
virtual const Type *type() = 0;
};
template<class T, const Type * myType>
class DataObjectValue : public DataObject
{
T value;
public:
const Type *type(){return myType;}
};
Но затем, когда я хочу выполнить, скажем, сложение, я должен сделать что-то вроде :
DataObject * sum(DataObject *a, DataObject *b)
{
if(a->type() == &Integer and b->type == &Integer)
{
DataObjectValue<int>* ia = dynamic_cast< DataObjectValue<int>* >(a);
DataObjectValue<int>* ib = dynamic_cast< DataObjectValue<int>* >(b);
return new DataObjectValue<int>(ia->value+ib->value);
}
else if(a->type() == &Real and b->type == &Real)
{
DataObjectValue<double>* ra = dynamic_cast< DataObjectValue<double>* >(a);
DataObjectValue<double>* rb = dynamic_cast< DataObjectValue<double>* >(b);
return new DataObjectValue<double>(ra->value+rb->value);
}
else...
}
Что становится довольно раздражающим довольно быстро (сделайте это для - * / < <= >= < > ....) и для нескольких других типов. Это трудно поддерживать. Конечно, я упростил процесс настолько, насколько мог придумать, внедрив повсюду множество шаблонов, но все же я не могу отделаться от мысли, что должен быть более чистый способ. Вы а) видите, в чем моя проблема (я сомневаюсь в своих объяснениях, а не в вашей компетентности) б) можете предложить что-нибудь?