Проблемы итератора C++

Работать с общими типами чисел может быть довольно неприятно, но как только вы их освоите, они не будут слишком плохими, хотя и немного более многословными. Стандартными строительными блоками для таких методов являются черты в ящике num от crates.io, в особенности Num , Zero и One , а также стандартные библиотеки std::cmp::PartialOrd .

Числовые литералы не могут быть универсальными для любого числового типа; они должны быть выполнены с помощью вызова метода trait; Zero::zero() и One::one() будет достаточно для большинства целей - здесь числа, которые мы хотим, это 0, 1, 2, 3, 5 и 6, которые в высшей степени достижимы с этими строительные блоки. Вы также можете создать свою собственную особенность с помощью статических методов, генерирующих эти значения, и реализовать их для любых числовых типов, которые вам нравятся, но лучше сделать это с помощью того, что гарантировано Num.

Основная процедура состоит в том, чтобы указать параметры вашего универсального типа как основанные на NumPartialOrd, если вы пишете неравенства для значений этого типа, таких как i * i <= n), и заменять любые числовые литералы на построенные от нуля до единицы, как показывает полдюжины let утверждений в начале метода, приведенного ниже. Обычно этого будет достаточно.

Вот что вы получите в итоге для этого конкретного метода:

// You’ll also need the appropriate dependencies.num addition to Cargo.toml
extern crate num;

use num::Num;

fn is_prime(n: N) -> bool {
    let _0 = N::zero();
    let _1 = N::one();
    let _2 = _1 + _1;
    let _3 = _2 + _1;
    let _5 = _2 + _3;
    let _6 = _3 + _3;
    if n == _2 || n == _3 {
        return true;
    } else if n % _2 == _0 || n % _3 == _0 {
        return false;
    }

    let mut i = _5;
    let mut w = _2;
    while i * i <= n {
        if n % i == _0 {
            return false;
        }
        i = i + w;
        w = _6 - w;
    }
    true
}

6
задан Mr Lister 1 May 2012 в 14:32
поделиться

2 ответа

Похоже, снова имя typename - я думаю, вам понадобится:

typename vector<State<T>*>::iterator it = ...

Эвристика для пользователей g ++ - когда вы видите это сообщение в коде шаблона:

expected `;' before ‘it’

это довольно хорошая ставка, что вещь перед "it" не рассматривается компилятором как тип и поэтому требует добавления "typename".

20
ответ дан 8 December 2019 в 04:31
поделиться

Это проблема синтаксического анализа. В этом коде vector *> :: iterator является вложенным зависимым типом.

Пока вы не узнаете, что такое T (и T не известен во время синтаксического анализа), синтаксический анализатор / compiler не понимает, что итератор является типом (может быть статической переменной-членом, насколько он знает).

Следовательно, вы должны префикс определения с typename в качестве подсказки, чтобы сообщить компилятору, что для всех vector *> , vector *> :: iterator - это имя типа.

5
ответ дан 8 December 2019 в 04:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: