Работать с общими типами чисел может быть довольно неприятно, но как только вы их освоите, они не будут слишком плохими, хотя и немного более многословными. Стандартными строительными блоками для таких методов являются черты в ящике num
от crates.io, в особенности Num
, Zero
и One
, а также стандартные библиотеки std::cmp::PartialOrd
.
Числовые литералы не могут быть универсальными для любого числового типа; они должны быть выполнены с помощью вызова метода trait; Zero::zero()
и One::one()
будет достаточно для большинства целей - здесь числа, которые мы хотим, это 0, 1, 2, 3, 5 и 6, которые в высшей степени достижимы с этими строительные блоки. Вы также можете создать свою собственную особенность с помощью статических методов, генерирующих эти значения, и реализовать их для любых числовых типов, которые вам нравятся, но лучше сделать это с помощью того, что гарантировано Num
.
Основная процедура состоит в том, чтобы указать параметры вашего универсального типа как основанные на Num
(и PartialOrd
, если вы пишете неравенства для значений этого типа, таких как 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
}
Похоже, снова имя typename - я думаю, вам понадобится:
typename vector<State<T>*>::iterator it = ...
Эвристика для пользователей g ++ - когда вы видите это сообщение в коде шаблона:
expected `;' before ‘it’
это довольно хорошая ставка, что вещь перед "it" не рассматривается компилятором как тип и поэтому требует добавления "typename".
Это проблема синтаксического анализа. В этом коде vector
является вложенным зависимым типом.
Пока вы не узнаете, что такое T (и T не известен во время синтаксического анализа), синтаксический анализатор / compiler не понимает, что итератор является типом (может быть статической переменной-членом, насколько он знает).
Следовательно, вы должны префикс определения с typename в качестве подсказки, чтобы сообщить компилятору, что для всех vector
, vector
- это имя типа.