Подтвердить что ты не робот

Генератор случайных чисел С++ 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), или я что-то пропустил?
  • Об этом упоминалось в отчете о дефектах?

Изменить: Я заметил, что этот отчет о дефекте, похоже, связан с этой проблемой.

4b9b3361

Ответ 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, на которое вы ссылались, также устраняет этот дефект.