Я склонен всегда использовать структурированный C++ пути к этому виду инициализации. Заметьте, что существенно, это не отличается, чем решение Altan. Программисту на C++ это просто выражает намерение немного лучше и могло бы быть более легким портативным устройством к другим типам данных. В этом экземпляре, функция C++ generate_n
экспрессы точно, что Вы хотите:
struct rnd_gen {
rnd_gen(char const* range = "abcdefghijklmnopqrstuvwxyz0123456789")
: range(range), len(std::strlen(range)) { }
char operator ()() const {
return range[static_cast(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * len)];
}
private:
char const* range;
std::size_t len;
};
std::generate_n(s, len, rnd_gen());
s[len] = '\0';
Между прочим, читайте эссе Julienne’s на том, почему это вычисление индекса предпочтено по более простым методам (как взятие модуля).
Чтобы дополнить другие ответы, я хотел бы описать, как это выяснить в общем случае. То есть, учитывая два преобразователя, какова семантика их двух комбинаций?
У меня было много проблем с этим вопросом, когда я начал использовать монадные преобразователи в проекте разбора на прошлой неделе. Мой подход состоял в том, чтобы создать таблицу преобразованных типов, к которой я обращаюсь всякий раз, когда я не уверен. Вот как я это сделал:
Шаг 1 : создайте таблицу основных типов монад и соответствующих им типов преобразователей:
transformer type base type (+ parameter order)
---------------------------------------------------------------
MaybeT m a m (Maybe a) b. Maybe b
StateT s m a s -> m (a, s) t b. t -> (b, t)
ListT m a m [a] b. [] b
ErrorT e m a m (Either e a) f b. Either f b
... etc. ...
Шаг 2: примените каждый монадный преобразователь к каждой из базовых монад, подставив вместо параметра типа m
:
inner outer combined type
Maybe MaybeT Maybe (Maybe a)
Maybe StateT s -> Maybe (a, s) -- <== this !!
... etc. ...
State MaybeT t -> (Maybe a, t) -- <== and this !!
State StateT s -> t -> ((a, s), t)
... etc. ...
(Этот шаг немного болезненный, поскольку существует квадратичное число комбинации ... но это было хорошее упражнение для меня, и мне нужно было сделать это только один раз.) Ключ для меня здесь в том, что я написал комбинированные типы развернутыми - без всех этих раздражающие обертки MaybeT, StateT и т. д. Мне намного проще смотреть и думать о типах без шаблона.
Чтобы ответить на ваш исходный вопрос, эта диаграмма показывает, что:
MaybeT + State :: t -> (Maybe a, t)
вычисление с сохранением состояния, в котором не может быть значения, но всегда будет (возможно, изменено) выход состояния
StateT + Maybe :: s -> Maybe (a, s)
вычисление, при котором и состояние, и значение могут отсутствовать
Вы сможете ответить на вопрос самостоятельно, если попытаетесь написать «запускающие» функции для обеих версий - у меня не установлены MTL + -трансформаторы, поэтому я не могу сделать это сам. Один вернет (может быть, состояние) другой Может быть (состояние) .
Редактировать - я обрезал свой ответ, так как он добавляет детали, которые могут сбить с толку. Ответ Джона ударяет гвоздь по голове.