Случайное перемешивание и указатели функций

У меня есть следующая функция, которая генерирует целое число в заданном диапазоне:

 18 int choosecard(){
 19     boost::uniform_int<> dist(0,51);
 20     boost::variate_generator< boost::mt19937&, boost::uniform_int<> > cardchoice(gen, dist);
 21     return cardchoice();
 22 }

Я хочу использовать его в качестве аргумента для std::random_shuffle, чтобы я мог перетасовать вектор из 52 целых чисел.

 64     int (*pchoosecard)(void) = choosecard;
 65 
 66     std::random_shuffle(cards.begin(), cards.end(), pchoosecard);

Однако я получаю эту ошибку, которую я не понимаю:

$ make
g++ -I /usr/local/boost_1_45_0/ -c main.cpp
In file included from /usr/include/c++/4.4/algorithm:62,
                 from /usr/local/boost_1_45_0/boost/any.hpp:13,
                 from /usr/local/boost_1_45_0/boost/program_options/value_semantic.hpp:12,
                 from /usr/local/boost_1_45_0/boost/program_options/options_description.hpp:13,
                 from /usr/local/boost_1_45_0/boost/program_options.hpp:15,
                 from main.cpp:1:
/usr/include/c++/4.4/bits/stl_algo.h: In function ‘void std::random_shuffle(_RAIter, _RAIter, _Generator&) [with _RAIter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, _Generator = int (*)()]’:
main.cpp:66:   instantiated from here
/usr/include/c++/4.4/bits/stl_algo.h:4998: error: too many arguments to function
make: *** [main.o] Error 1

Все компилируется нормально, когда я закомментирую строку, вызывающую std::random_shuffle.

Кто-нибудь может пролить свет на эту проблему?


person oadams    schedule 04.12.2010    source источник


Ответы (2)


Существует «слишком много аргументов», потому что std::random_shuffle пытается передать слишком много аргументов обратному вызову, который вы ему дали. Так что это действительно слишком мало параметров.

Предполагается, что ваш choosecard принимает один параметр типа ptrdiff_t, который в основном сообщает функции количество элементов. (Вы не должны жестко кодировать количество карт в этой функции.) Поэтому вы подключаете это к конструктору boost::uniform_dist.

person Karl Knechtel    schedule 04.12.2010
comment
Спасибо, но я все еще в замешательстве. У меня нет конструктора uniform_dist. Вы имеете в виду строку с boost::uniform_int‹› dist(0,51)? Я заставил selectcard взять ptrdiff_t, т.е. А затем изменил вышеупомянутую строку на boost::uniform_int‹› dist(0,i-1); Однако я просто получаю больше загадочных ошибок - person oadams; 04.12.2010

Из http://www.cplusplus.com/reference/algorithm/random_shuffle/:

template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle ( RandomAccessIterator first, RandomAccessIterator last,
                      RandomNumberGenerator& rand );

первый, последний

Перенаправьте итераторы в начальную и конечную позиции последовательности, которую нужно перемешать. Используется диапазон [first,last), который содержит все элементы между first и last, включая элемент, на который указывает first, но не элемент, на который указывает last.

ранд

Указатель на унарную функцию, принимающую один аргумент и возвращающую значение соответствующего разностного типа (обычно ptrdiff_t). Функция должна возвращать значение между нулем и своим аргументом (ниже этого).

person Lie Ryan    schedule 04.12.2010