Как передать аргумент функции - работа со ссылкой

0

У меня есть некоторые проблемы с 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);

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

Как передать больше аргументов этой функции?

  • 2
    Он передает указатель на функцию. genome.initializer берет указатель и вызывает функцию столько раз, сколько необходимо. Если вы хотите, чтобы функция принимала больше аргументов, вам нужно сначала изменить тип (сигнатуру) ожидаемой функции (что-то вроде void (*f)(GAGenome&, int) ), а затем каждый раз, когда initializer вызывает f , передавать дополнительный аргумент.
Теги:
pass-by-reference

2 ответа

2
Лучший ответ

Линейный genome.initializer(TreeInitializer); не вызывает TreeInitializer - вместо этого он передает указатель на эту функцию в genome.initializer, поэтому он может вызывать его любыми аргументами, которые ему нужны/несколько раз. Если вы хотите, чтобы TreeInitializer принимал больше аргументов, вам нужно изменить initializer чтобы принять другой тип функции. Вероятно, это определяется как

void initializer(void (*f)(GAGenome&))
{
    // ...
    f(genome);
    // ...
}

Вам нужно изменить тип аргумента на void (*f)(GAGenome&, int) и изменить строки, вызывающие f.

С другой стороны, если вы не можете изменить функцию инициализатора, но хотите указать глубину, то лучше всего сделать глобальную переменную, которую вы установите на любую глубину, в которой вы нуждаетесь, и использовать TreeInitializer эту переменную. Это не чистое решение, если вы считаете, что глобальные переменные являются злыми, но это ваш единственный выбор, если initializer не позволяет вам предоставлять какой-либо "контекст".

  • 0
    У меня есть больше переменных для передачи, поэтому я не хотел использовать глобальные переменные, но знаю, что я думаю, это самый быстрый способ. Я нашел в коде библиотеки это: <code> typedef void (* Initializer) (GAGenome &); </ code> и далее <code> void initialize () {_ оценочный = gaFalse; _neval = 0; (* init) (* this);} Initializer initializer () const {return init;} Initializer initializer (Initializer op) {return (init = op);} </ code> Так что между этим и вашим примером все немного отличается. Что я должен изменить?
  • 1
    Если вы действительно хотите изменить код библиотеки, чтобы позволить вам передать дополнительный аргумент (в зависимости от вас, сможете ли вы определить, имеет ли это смысл), вам нужно добавить второй аргумент в typedef ( typedef void (Initializer)(GAGenome&,int) ), а затем добавить элемент Int к классу, сделать так , чтобы установить его (вероятно , из initializer функции), и initialize() вызов (*init)(*this, value) , где value является членом переменная, которую вы добавили.
-2

Что вы делаете в

GATreeGenome<int> &child=(GATreeGenome<int> &)c;

это кастинг от GAGenome до GATreeGenome. Если у вас нет оператора кастингов для этого случая, он не будет работать...

  • 0
    Приведение будет работать, даже если оператор преобразования не предоставлен. Ваш ответ не касается реального вопроса. -1.
  • 0
    Почему? GATreeGenome <int> и GaGenome - это два разных класса.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню