2016-03-20 5 views
1

В C++ существует ли предпочтительный способ работы с рекурсивной функцией, которая каждый раз повторно использует неизменный объект? Например (псевдо-код):Рекурсивные функции с постоянными параметрами

void func(HashMap h, Logger logger, int depth) 
{ 
    // Do stuff then call func recursively... 
    func(h, logger, depth+1); 
} 

Так каждый звонок мы переходим в нескольких объектов (хэш-карты и регистратора) без изменений. Да, мы можем пройти по ссылке, но она все еще кажется неэффективной и выглядит не очень красивой. Единственная альтернатива, о которой я могу думать, это глобальные переменные или объединение константных параметров в структуре.

+2

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

+0

В C++ собираются константные параметры в структуре и передаются по ссылке –

+0

'Да, мы можем пройти по ссылке, но все равно кажется неэффективной', молись объяснить? – txtechhelp

ответ

0

Это совершенно чистый код, который точно отражает то, что происходит. Конечно, в C++ вы должны передать HashMap и Logger в качестве ссылки на const.

С точки зрения производительности, однако, возможно, было бы лучше сделать эти две переменные класса объектов. Но это может затруднить понимание кода, поэтому просто сделайте это, если у вас действительно есть проблема с производительностью.

Кстати, что делает функция, если она не изменяет HashMap и возвращает void?

+0

В моем случае хэш-файл был только прочитан и предоставил некоторые поисковые запросы для обработки в рекурсивной функции. – SteevieP

+0

@SteevieP: Значит, основной эффект функции - это побочный эффект? Обычно это не считается хорошим дизайном, особенно для рекурсивной функции. –

0

То, что вы описываете, является закрытой лексической средой, иначе называемой «закрытием». Эта концепция существует «бесплатно» в динамических языках, таких как Lisp и Scheme, где шаблон «let lambda» позволяет вам захватывать переменные в функции и использовать их, даже несмотря на то, что их охватывающая область исчезла или вышла.

Вы можете имитировать замыкания на C++ с помощью struct в качестве контейнера для захваченных переменных и применять функции (функторы) к struct. Наиболее распространенная схема для этого, как правило, так что operator() используется:

struct my_closure { 
    Hashmap &hmap_; 
    Logger &logger_; 
    int depth_; 

    my_closure(Hashmap &hmap, Logger &logger, int depth) : 
    hmap_(hmap), logger_(logger), depth_(depth) 
    { } 

    void operator()(void) 
    { /* do stuff here, including recurse */ } 
}; 

Единственное, это сэкономит вам толкает дополнительный материал в стеке, который не обязательно спасет вас много с точки зрения циклов (1 struct reference [ указатель на структуру] и 2 ссылки + 1 целое.) Если ваш компилятор поддерживает хвостовую рекурсию, это может быть полезно за счет удобочитаемости.

+0

C++ 11 поддерживает замыкания. Поэтому вам больше не нужно создавать выделенную структуру (с глупым именем). –

+0

@FrankPuffer: Полезно понять, как создать его, когда у вас нет оборудования C++ 11 в вашем распоряжении. Поскольку понимание того, что указывает на функции, заключается в том, как реализовать виртуальные функции. –

Смежные вопросы