2016-01-31 19 views
2

Я задавал себе вопрос, почемуПочему const std :: random_device невозможен?

#include <random> 
struct A{  
    std::random_device rd; // or any other generator std::mersenne_twister... 

    void doStuff() const { 
     auto v = rd(); 
    } 

}; 

const A a; 
a.doStuff(); 

не работает, так как random_device::operator() не const.

Я думал, может быть случайное устройство по-прежнему может использоваться при постоянной, но она не может быть посеяны еще раз, но это не тот случай (внутреннее состояние, очевидно, не изменяемые в std::random_device) ...

Я хочу сделать класс A правильно определено (doStuff() - метод const), и теперь мне вдруг нужно использовать mutable std::random_device rd;, не так ли уродливо?

Есть ли причина для этого дизайна?

+3

Ваше название задает тонкий вопрос о том, что текст тела. Название спрашивает, почему он не может быть const; но, похоже, вы уже понимаете это - тело вместо этого спрашивает, почему оно не предназначено для разрешения const - это другой вопрос. Таким образом, вы, скорее всего, получите ответы, которые касаются названия, и просто скажите, что вы уже знаете. То, что вы на самом деле спрашиваете, может быть вопросом мнения и дебатов, и это не поощряется к SO. – Clifford

+1

"или любой другой генератор std :: mersenne_twister" Вы спрашиваете конкретно о 'random_device' или о любом другом генераторе? –

+4

Это прекрасный пример того, когда использовать 'mutable', это не уродливо. –

ответ

7

const может означать много вещей. Это может означать любое или все из следующего:

  1. Учитывая то же состояние и параметры объекта, тот же результат будет иметь место.

  2. Функция не изменит внутреннее состояние объекта, на котором он работает.

  3. Функция получает доступ к состоянию объекта в thread-safe way.

Ни один из этих не верно для random_device::operator(). Вы получите разные результаты; вот и вся функция. Состояние, которое является внутренним для объекта, будет зависеть от его запроса (так или иначе). И функция, безусловно, не thread-safe; призывая его к одному и тому же объекту из разных потоков, может вызвать все усадьбу плохости.

То же самое относится к любому RNG. Получение случайного числа из RNG составляет по существу непостоянный процесс. Вот почему для разработки RNG C++ 11 требуется, чтобы operator() не был объявлен const.

Что касается вашей цели:

Я хочу сделать класс А быть правильно определена (doStuff() является константной метод), а теперь я вдруг нужно использовать mutable std::random_device rd; не то, что некрасиво?

Это зависит от того, что вы подразумеваете под const. Очевидно, что № 2 отсутствует, так как вы будете менять состояние mutable. Тем не менее, вы по-прежнему можете предоставить № 1 для конкретного определения «того же результата». То есть, «материал», который делает doStuff, будет логически последовательным. Не бинарно идентично, очевидно, но в рамках поведения функции. Этого достаточно, чтобы быть const.

И вы даже можете предоставить №3, путем обертывания вашего доступа к вашему объекту RNG в мьютексе.

Случаи, подобные этому, именно поэтому mutable был изобретен. Это не уродливо; вы просто используете функцию для того, для чего она предназначена. Чтобы разрешить доступ к некоторым объектам, отличным от const, логически constвызывающему абоненту.

+0

ах хорошее объяснение :-), хотя изменчивый всегда плохой дизайн ... – Gabriel

9

std::randome_device::operator()() не является const, так как он может изменять внутреннее состояние объекта. std::random_device может быть генератором псевдослучайных чисел, который использует внутреннее состояние для генерирования чисел. Каждый раз, когда вы создаете номер, вам нужно изменить внутреннее состояние, иначе вы получите один и тот же номер каждый раз.

+0

Да, конечно, это абсолютно нормально :-) Я просто замечаю, что это делает использование PRNG в качестве члена класса, потенциально изменяемого ... только из-за этого ... – Gabriel

+0

Насколько мне кажется, Габриэль понял. Он не спрашивает, почему он не может быть const (хотя название может предложить это), но почему он * разработан * таким образом, когда внутреннее состояние является проблемой реализации и может быть изменчивым. Ответ, который, однако, может быть просто мнением, если только стандарт ИСО не имеет каких-либо особенностей, чтобы сказать об этом. – Clifford

Смежные вопросы