Генератор случайных чисел С++ 11 Интерпретация UIntType
Раздел 26.5.1.1, пункт 1 стандарта С++ 11 (N3242) гласит:
В этом подпункте 26.5 эффект создания шаблона:
[...]
f), который имеет параметр типа шаблона с именем UIntType
, является undefined, если соответствующий шаблон аргумент cv-unqualified и является одним из unsigned short
, unsigned int
, unsigned long
или unsigned long long
.
И он определяет линейный конгруэнтный генератор в 26.5.3.1. Определение класса начинается следующим образом:
template<class UIntType, UIntType a, UIntType c, UIntType m>
class linear_congruential_engine
minstd_rand0
, похоже, нарушает это ограничение:
typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
minstd_rand0;
Поскольку он использует uint_fast32_t (который не гарантированно является одним из unsigned short
, unsigned int
, unsigned long
или unsigned long long
) в minstd_rand0
для параметра шаблона с именем UIntType
, он выглядит как имеют эффект undefined для #include <random>
или, по крайней мере, для использования minstd_rand0
. Эта проблема также применима и к другим предопределенным RNG, и она не исправлена в С++ 14.
Мои вопросы:
- Это действительно противоречие (или, скорее, экстремальное количество поведения undefined), или я что-то пропустил?
- Об этом упоминалось в отчете о дефектах?
Изменить: Я заметил, что этот отчет о дефекте, похоже, связан с этой проблемой.
Ответы
Ответ 1
Да и нет. В разделе 18.4.1, uint_fast32_t
Должен быть псевдоним для целочисленного типа без знака. В то время как единственные целые типы без знака в С++ без знака char, short, int, long, long, long (3.9.1) Таким образом, единственный сценарий, который вы упомянули выше, может быть противоречием в том, что char - это как-то 32- бит или шире, а uint_fast32_t определяется псевдонимом без знака char.
Ответ 2
uint_fast32_t указывается как самый быстрый целочисленный тип без знака с шириной не менее 32 бит.
В системе типа С++ оба типа символов и целочисленных типов являются целыми типами, но типы символов не являются целыми типами (и наоборот).
Наконец, целые типы без знака - это те, которые перечислены для случайных генераторов.
Мое заключение заключается в том, что использование uint_fast32_t соответствует стандарту (если я не пропустил какую-либо часть стандарта, где для uint_fast32_t для типа unstsndard, или для определения целочисленного типа, чтобы включить нестандартные типы, это специально разрешено).
Однако я считаю, что спецификация должна быть исправлена, чтобы попытаться избежать неоднозначных интерпретаций.
Ответ 3
Я не эксперт, но я отвечаю, что да, это дефект, если вы правы, что uint_fast32_t
не обязательно должен быть одним из этих типов в соответствии со стандартом.
Предъявленное вами решение NAD 2326, на которое вы ссылались, также устраняет этот дефект.