Эквивалентный образец генератора C ++ для Python - PullRequest
97 голосов
/ 30 января 2012

У меня есть пример кода Python, который мне нужно имитировать в C ++.Мне не требуется никакого конкретного решения (например, решения для доходности, основанного на совместной подпрограмме, хотя они также были бы приемлемыми ответами), мне просто нужно каким-то образом воспроизвести семантику.

Python

Это базовый генератор последовательности, явно слишком большой, чтобы хранить материализованную версию.

def pair_sequence():
    for i in range(2**32):
        for j in range(2**32):
            yield (i, j)

Цель состоит в том, чтобы поддерживать два экземпляра последовательности, описанной выше, и выполнять их итерацию в полусвободном шаге, но порциями,В приведенном ниже примере first_pass использует последовательность пар для инициализации буфера, а second_pass регенерирует такую ​​же точную последовательность и снова обрабатывает буфер.

def run():
    seq1 = pair_sequence()
    seq2 = pair_sequence()

    buffer = [0] * 1000
    first_pass(seq1, buffer)
    second_pass(seq2, buffer)
    ... repeat ...

C ++

Единственное, что я могу найти для решения в C ++, это имитировать yield с сопрограммами C ++, но я не нашел какой-либо хорошей ссылки на то, как это сделать.Я также заинтересован в альтернативных (не общих) решениях этой проблемы.У меня недостаточно памяти, чтобы хранить копию последовательности между проходами.

Ответы [ 11 ]

0 голосов
/ 01 января 2017

Так же, как функция имитирует концепцию стека, генераторы имитируют концепцию очереди. Остальное семантика.

В качестве примечания вы всегда можете смоделировать очередь со стеком, используя стек данных вместо данных. Практически это означает, что вы можете реализовать поведение, подобное очереди, возвращая пару, второе значение которой либо имеет следующую вызываемую функцию, либо указывает, что у нас нет значений. Но это более общее, чем то, что делает yield против return. Он позволяет имитировать очередь любых значений, а не однородных значений, которые вы ожидаете от генератора, но без сохранения полной внутренней очереди.

Более конкретно, поскольку в C ++ нет естественной абстракции для очереди, вам необходимо использовать конструкции, которые реализуют очередь внутренне. Таким образом, ответ, который привел пример с итераторами, является достойной реализацией концепции.

Что это означает на практике, так это то, что вы можете реализовать что-то с функциональностью очереди без посредников, если вам просто нужно что-то быстрое, а затем использовать значения очереди так же, как вы будете использовать значения, полученные из генератора.

...