const
может означать много вещей. Это может означать любое или все из следующего:
Учитывая то же состояние и параметры объекта, тот же результат будет иметь место.
Функция не изменит внутреннее состояние объекта, на котором он работает.
Функция получает доступ к состоянию объекта в 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
вызывающему абоненту.
Ваше название задает тонкий вопрос о том, что текст тела. Название спрашивает, почему он не может быть const; но, похоже, вы уже понимаете это - тело вместо этого спрашивает, почему оно не предназначено для разрешения const - это другой вопрос. Таким образом, вы, скорее всего, получите ответы, которые касаются названия, и просто скажите, что вы уже знаете. То, что вы на самом деле спрашиваете, может быть вопросом мнения и дебатов, и это не поощряется к SO. – Clifford
"или любой другой генератор std :: mersenne_twister" Вы спрашиваете конкретно о 'random_device' или о любом другом генераторе? –
Это прекрасный пример того, когда использовать 'mutable', это не уродливо. –