Я пишу парсер аргументов командной строки для приложения. Они могут быть трех типов: логические, строковые или числовые. Данный аргумент будет ожидать данного типа, поэтому здесь нет догадок.
Я решил представить аргумент в виде класса с именем Arg
. Один и тот же переключатель может появляться несколько раз, поэтому я хочу отслеживать идентичность, отсюда и класс.
Дело в том, что, хотя в игре несколько типов, обработка всегда более или менее одинакова. Чтобы избежать написания кода, я подумал, что могу создать шаблон класса Arg
, по сути, так:
class Arg(T)
{
public:
T value;
this(T defaultValue)
{
value=defaultValue;
}
}
Моя проблема в том, что в идеале я бы просто складывал их в динамический массив, но сначала мне нужно было бы узнать их тип: я не могу точно объявить массив как Arg!whatever[] myArray
.
Я, очевидно, могу использовать базовый тип, что-то вроде Object[] array
. Дело в том, что мне нужно будет привести каждый элемент массива перед его использованием. Я мог бы написать вспомогательную функцию для этого, но это вряд ли кажется идиоматическим. Я бы, однако, держал все связанные с типом боли в одной функции. (это то, что я бы сделал без внешнего совета)
Полагаю, я мог бы также поддерживать отдельные массивы. Но это не слишком удобно: мне нужно подумать о различных числовых типах, и если бы я добавил новые типы аргументов, мне пришлось бы добавить новые массивы.
Я также пытался использовать std.variant
, но не нашел их слишком удобными для моих целей. Возможно, я использовал их неправильно, но я обнаружил, что мне приходится писать точно такие же функции с несколькими сигнатурами в форме:
Algebraic!(string, bool, int) value;
this(string defaultValue) { this.value=defaultValue; }
this( bool defaultValue) { this.value=defaultValue; }
this( int defaultValue) { this.value=defaultValue; }
Что вряд ли похоже на умную работу.
Как правильно поступить?
Спасибо за помощь!