Инициализация boost :: random :: discrete_distribution в VC2010 - PullRequest
1 голос
/ 25 октября 2011

Я пытаюсь реализовать один из первых примеров из документации boost :: random в Visual Studio 2010 SP1, используя собственную библиотеку (TR1).

Раньше, при использовании библиотеки, я обнаружил, что могу просто использовать встроенные случайные функции VC2010, и они работают так же, как расширенные функции, но здесь я не могу использовать встроенные функции.

Проблема с инициализацией discrete_distribution<> в VC2010. В Boost он принимает массив:

double probabilities[] =
{
    0.5, 0.1, 0.1, 0.1, 0.1, 0.1
};
boost::random::discrete_distribution<> dist( probabilities );

Но в VC2010 я не знаю, чем мне его снабжать. Вот ошибка, которую я получаю при компиляции:

Причина: невозможно преобразовать из 'double [6]' в 'const std :: tr1 :: discrete_distribution <> :: param_type'

Ни один конструктор не может принять тип источника, или разрешение перегрузки конструктора было неоднозначным

Я думал, что, поскольку эти функции реализованы в VC2010, я могу просто использовать встроенные, сохраняя многоплатформенную совместимость, но, похоже, мне придется прибегнуть к использованию классов boost.

Существуют ли какие-либо потери производительности для использования boost :: random по сравнению со встроенным классом в VC2010?

Как правило, рекомендуется придерживаться библиотек Boost, даже если они сейчас реализованы в большинстве компиляторов C ++?

Вот две вставки рабочего и нерабочего кода:

Неработающий модифицированный пример с использованием std

Рабочий оригинальный пример с использованием boost :: random

Кроме того, что означает эта строка на странице boost doc ?

Совет. Если ваш компилятор поддерживает std :: initializer_list, вы можете инициализировать discrete_distribution непосредственно с весами.

1 Ответ

0 голосов
/ 25 октября 2011

VC2010 std::tr1::discrete_distribution не соответствует последней спецификации C ++ 11 (отсюда и пространство имен tr1) и пока не предоставляет всех способов его создания.На самом деле, кажется, что единственный способ построить его в VC2010 - это либо инициализировать его по умолчанию, либо предоставить генератор, который вызывается N раз: http://msdn.microsoft.com/en-us/library/ee462277.aspx

Конструктор, который принимает const param_type& по сути одно и то же: http://msdn.microsoft.com/en-us/library/ee462364.aspx

В действительной спецификации C ++ 11 есть еще две перегрузки для конструктора discrete_distribution, а именно одна, которая принимает два входных итератора, и одна, которая принимаетa std::initializer_list, что приводит нас ко второму вопросу.

Совет Если ваш компилятор поддерживает std :: initializer_list, вы можете инициализировать discrete_distribution непосредственно с весами.

std::initializer_list - это новая функция C ++ 11 , которая в основном позволяет инициализировать не только массивы и структуры POD со списком инициализаторов, но и более сложные типы классов, если конструкторы принимают std::initializer_list (они также могут быть использованы для других целей, кроме инициализации новых объектов).Запись в Википедии содержит больше информации, и идея довольно проста, поэтому я не буду вдаваться в подробности здесь.Но в основном это означает, что вместо выполнения:

double probabilities[] =
{
    0.5, 0.1, 0.1, 0.1, 0.1, 0.1
};
boost::random::discrete_distribution<> dist( probabilities );

Вы можете просто сделать:

boost::random::discrete_distribution<> dist( {0.5, 0.1, 0.1, 0.1, 0.1, 0.1} );

Конструкция в списке параметров конструктора создает std::initializer_list<double> и затем передает егоboost::random::discrete_distribution<> конструктор.

Причина, по которой VC2010 пока не поддерживает это, состоит в том, что VC2010 пока не поддерживает std::initializer_list (он имеет только частичную поддержку C ++ 11).

При этом, как представляется, в текущей реализации VC2010 std::tr1::discrete_distribution, похоже, не хватает, и единственный способ ее инициализации, по-видимому, заключается в использовании функции генератора, поэтому я сам остановлюсь на улучшенной версии.

Даже если вы используете компилятор, полностью соответствующий спецификации C ++ 11, Boost по-прежнему может предложить lot .C ++ 11 ни в коей мере не предлагает все, что может предложить boost, и нет причин полностью отказываться от boost при использовании C ++ 11.Однако, если вы пишете код на C ++ 11, то, очевидно, имеет смысл использовать эквиваленты C ++ 11 тех возможностей, которые он предлагает по сравнению с расширенными версиями, поскольку они могут иметь специфичные для конкретного поставщика оптимизации.

Многие люди по-прежнемувыбирайте C ++ 03 вместо C ++ 11, так как пройдет достаточно времени, пока C ++ 11 полностью не будет поддержан всеми основными производителями компиляторов, поэтому в таких случаях это расширенные эквиваленты возможностей, которые C ++ 11также предлагает вам еще очень полезны

...