Функция шаблона, которая вызывает сама себя, приводит к "глубине создания экземпляра превышает максимум 900". - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь создать функцию, которая принимает обратный вызов лямбда-функции и некоторые candidate_primes, которые могут быть set или vector, но выдает ошибку:

шаблон глубина создания экземпляра превышает максимум 900

template<class PrimeIter, class Function>
void iter_feasable_primes(
  const PrimeIter& candidate_primes, const uint32_t larger_prime, uint8_t index, Function cb
) {
  std::vector<uint32_t> next_candidate_primes;
  for (const uint32_t p : candidate_primes) {
    // Updates next_candidate_primes
  }
  if (index == 0) {
    // No valid tuples of primes were found
    return;
  }
  for (const uint32_t p : next_candidate_primes) {
    iter_feasable_primes(next_candidate_primes, p, index - 1, [&](std::vector<uint32_t> smaller_primes) {
      smaller_primes.push_back(p);
      cb(smaller_primes);
    });
  }
}

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

Как я могу решить эту проблему?

Я попытался сделать index параметром шаблона безрезультатно, поскольку компилятор, похоже, не понимает, что он никогда не дойдет до index = -1, и жалуется мне, что -1 не определен. Но в идеале я не хочу, чтобы index было параметром шаблона.

1 Ответ

2 голосов
/ 04 августа 2020

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

Один из способов решения этой проблемы - дать уникальный тип, либо пользовательский функтор, либо тип со стиранием типа std::function

template<class PrimeIter>
void iter_feasable_primes(
  const PrimeIter& candidate_primes,
  uint32_t larger_prime,
  uint8_t index,
  std::function<void(std::vector<uint32_t>)> cb)
{
  std::vector<uint32_t> next_candidate_primes;
  for (const uint32_t p : candidate_primes) {
    // Updates next_candidate_primes
  }
  if (index == 0) {
    // No valid tuples of primes were found
    return;
  }
  for (const uint32_t p : next_candidate_primes) {
    iter_feasable_primes(next_candidate_primes, p, index - 1, [&](std::vector<uint32_t> smaller_primes) {
      smaller_primes.push_back(p);
      cb(smaller_primes);
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...