У меня есть некоторые проблемы с C++. Я создаю приложение с использованием библиотеки GAlib (это библиотека C++ компонентов генетического алгоритма - http://lancet.mit.edu/ga/).
В одном из примеров (полный код примера: http://lancet.mit.edu/galib-2.4/examples/ex6.C) автор создает функцию, которая инициализирует дерево:
void TreeInitializer(GAGenome & c)
{
GATreeGenome<int> &child=(GATreeGenome<int> &)c;
// destroy any pre-existing tree
child.root();
child.destroy();
// Create a new tree with depth of 'depth' and each eldest node containing
// 'n' children (the other siblings have none).
int depth=2, n=2, count=0;
child.insert(count++,GATreeBASE::ROOT);
for(int i=0; i<depth; i++){
child.eldest();
child.insert(count++);
for(int j=0; j<n; j++)
child.insert(count++,GATreeBASE::AFTER);
}
}
Он вызывает функцию таким образом:
genome.initializer(TreeInitializer);
и Он не дает аргумента. Когда я пытаюсь передать аргумент этой функции, изменяя объявление, например:
void TreeInitializer(GAGenome &, int deph);
Компилятор показывает мне ошибки. Я не знаю, как правильно вызвать эту функцию. Я знаю, что это связано с ссылкой, но передача (или не прохождение) аргумента таким образом нова для меня.
Как передать больше аргументов этой функции?
Линейный genome.initializer(TreeInitializer);
не вызывает TreeInitializer
- вместо этого он передает указатель на эту функцию в genome.initializer
, поэтому он может вызывать его любыми аргументами, которые ему нужны/несколько раз. Если вы хотите, чтобы TreeInitializer
принимал больше аргументов, вам нужно изменить initializer
чтобы принять другой тип функции. Вероятно, это определяется как
void initializer(void (*f)(GAGenome&))
{
// ...
f(genome);
// ...
}
Вам нужно изменить тип аргумента на void (*f)(GAGenome&, int)
и изменить строки, вызывающие f
.
С другой стороны, если вы не можете изменить функцию инициализатора, но хотите указать глубину, то лучше всего сделать глобальную переменную, которую вы установите на любую глубину, в которой вы нуждаетесь, и использовать TreeInitializer
эту переменную. Это не чистое решение, если вы считаете, что глобальные переменные являются злыми, но это ваш единственный выбор, если initializer
не позволяет вам предоставлять какой-либо "контекст".
typedef void (Initializer)(GAGenome&,int)
), а затем добавить элемент Int к классу, сделать так , чтобы установить его (вероятно , из initializer
функции), и initialize()
вызов (*init)(*this, value)
, где value
является членом переменная, которую вы добавили.
Что вы делаете в
GATreeGenome<int> &child=(GATreeGenome<int> &)c;
это кастинг от GAGenome до GATreeGenome. Если у вас нет оператора кастингов для этого случая, он не будет работать...
genome.initializer
берет указатель и вызывает функцию столько раз, сколько необходимо. Если вы хотите, чтобы функция принимала больше аргументов, вам нужно сначала изменить тип (сигнатуру) ожидаемой функции (что-то вродеvoid (*f)(GAGenome&, int)
), а затем каждый раз, когдаinitializer
вызываетf
, передавать дополнительный аргумент.