2011-10-27 15 views
8

Załóżmy, że w C++ robisz zbyt wiele wywołań rekursywnych na funkcji rekurencyjnej i otrzymujesz błąd przepełnienia stosu.W jaki sposób C++ może używać stylu przekazywania kontynuacji?

W jaki sposób przepisałbyś to w stylu przekazywania kontynuacji, aby uniknąć przepełnienia stosu?

Mam niewielką trudność zobrazowania tego w C++.

+2

Nie dostaniesz niczego oprócz abstrakcyjnych odpowiedzi na tak abstrakcyjne pytanie. Może powinieneś opublikować przykładową funkcję, która powoduje przepełnienie stosu, wtedy otrzymasz konkretne odpowiedzi, jak to naprawić. (I osobiście, spróbowałbym przepisać funkcję, aby użyć akumulatora przed przepisaniem go na kontynuację ...) – ildjarn

+0

Jesteś we właściwym miejscu. –

+0

@ildjarn, dzięki za uwagę. Właściwie szukam abstrakcyjnej odpowiedzi. Jeśli użyję akumulatora, czy nie będę go przepisywać jako normalnej iteracji w C++? – achow

Odpowiedz

4

Cóż, to raczej otwarte pytanie, ale Eric Lippert napisał (dobrze dwie właściwie) raczej long series about exactly this topic. Niezupełnie odpowiedni język, ale powinien być raczej pomocny i dać ogólny pomysł.

Chociaż implementacja CPS w C++ wydaje się być bardzo pracochłonna, aby naprawić pojedynczą funkcję rekursywną, kiedy można po prostu użyć jakiegoś algorytmu do iteracyjnej funkcji z kolejką (nadal używa się w zasadzie tej samej ilości danych, ale sterty są znacznie mniej ograniczone).

+1

Miałem wyraźną korzyść z pisania obu tych serii w kontekście języków, które mają zamknięcia leksykalne jako wbudowane funkcje językowe. Przepisanie kodu C++ do zamknięć jest oczywiście całkowicie osiągalne, ale będzie to trochę uciążliwe. –

+1

@EricLippert Masz rację Zakładam C++ 11 lambdas, ale oczywiście nie wszyscy (no, nawet nie zbliżeni do większości) ma kompilator obsługujący lambdas. Bez tego staje się to o wiele bardziej skomplikowane (wykorzystuj klasy i przypuszczalnie omiń je w pobliżu?). Dziękuję za twoje wspaniałe artykuły - bez ciebie nie wiedziałbym nawet czym jest CPS :) – Voo

+2

@Voo: Nawet bez C++ 11 lambd, istnieją biblioteki C++ 03, które radzą sobie z tym w sposób trywialny. Zobacz np. [Boost.Phoenix] (http://www.boost.org/libs/phoenix/). – ildjarn

Powiązane problemy