Вот полный рабочий пример .
Ваша первая проблема, я думаю, использует несколько ReactDOM.render
с. Боюсь, это не тот случай использования. Вы должны использовать это один раз.
Вторая проблема, которую я вижу, - это дублирование вашей навигации три раза. Если вы извлечете это в свой собственный компонент и вызовете его Navigation
, вы можете отрендерить его только один раз. Например:
function Navigation(props) {
return (
)}
Тогда вы можете использовать его следующим образом:
function Main() {
const [page, setPage] = useState("playground");
return (
{page === "playground" && }
{page === "technology" && }
{page === "library" && }
);
}
react-router
для маршрута на основе рендеринга компонентов, то вам нужно ввести state
и переключить компонент на основе state
. В вышеупомянутом компоненте Main
у меня есть одно состояние, которое может содержать playground
, technology
или library
и на основе текущего значения мы визуализируем соответствующий компонент. В этом нет ничего плохого, но это, безусловно, ограничит использование шаблона. Вы не сможете просто поместить итератор, возвращенный чем-то другим или сгенерированный как v.begin ()
, поскольку это будут временные. Вам всегда сначала придется делать локальную копию, которая является своего рода шаблоном, который не очень хорошо иметь.
Один из способов - перегрузить его:
int parse_integer(input_iterator begin, input_iterator end,
input_iterator &newbegin);
template<typename input_iterator>
int parse_integer(input_iterator begin, input_iterator end) {
return parse_integer(begin, end, begin);
}
Другой вариант - иметь итератор вывода, в который будет записано число:
template<typename input_iterator, typename output_iterator>
input_iterator parse_integer(input_iterator begin, input_iterator end,
output_iterator out);
У вас будет возвращаемое значение для возврата нового итератора ввода. Затем вы можете использовать итератор вставки, чтобы поместить проанализированные числа в вектор или указатель, чтобы поместить их непосредственно в целое число или его массив, если вы уже знаете количество чисел.
int i;
b = parse_integer(b, end, &i);
std::vector<int> numbers;
b = parse_integer(b, end, std::back_inserter(numbers));
Когда они говорят «не передавать по ссылке», возможно, это потому, что более нормально / идиоматично передавать итераторы в качестве параметров значения, вместо того, чтобы передавать их по константной ссылке: что вы и сделали, для второй параметр.
Однако в этом примере вам нужно вернуть два значения: проанализированное значение int и новое / измененное значение итератора; и учитывая, что функция не может иметь два кода возврата, кодирование одного из кодов возврата как неконстантной ссылки является нормой IMO.
Альтернативой может быть кодирование его примерно так:
//Comment: the return code is a pair of values, i.e. the parsed int and etc ...
pair<int, input_iterator> parse(input_iterator start, input_iterator end)
{
}
На мой взгляд, если вы хотите сделать это, аргумент должен быть указателем на итератор, который вы измените. Я не большой поклонник неконстантных ссылочных аргументов, потому что они скрывают тот факт, что переданный параметр может измениться. Я знаю, что есть много пользователей C ++, которые не согласны с моим мнением по этому поводу - и это нормально.
Однако в данном случае это , поэтому итераторы обычно рассматриваются как аргументы значения, которые я считаю особенно плохая идея передавать итераторы по неконстантной ссылке и изменять переданный итератор. Это просто противоречит идиоматическому способу использования итераторов.
Поскольку есть отличный способ делать то, что вы хотите, без этой проблемы, я думаю, вам следует его использовать:
template <typename input_iterator>
int parse_integer(input_iterator* begin, input_iterator end);
Теперь вызывающий должен будет делать:
int i = parse_integer(&p, end);
И это ' Будет очевидно, что итератор можно изменить.
Кстати, мне также нравится предложение litb о возврате нового итератора и помещении проанализированных значений в место, указанное итератором вывода.
Из perlfaq8:
Как мне добавить каталог, в котором находится моя программа, в путь поиска модуля / библиотеки?
(предоставлено brian d foy)
Если вы уже знаете каталог, вы можете добавить его в @INC, как и любой другой каталог. Вы можете использовать lib, если знаете каталог во время компиляции:
use lib $directory;
Уловка в этой задаче состоит в том, чтобы найти каталог. Прежде чем ваш сценарий сделает что-либо еще (например, chdir), вы можете получить текущий рабочий каталог с помощью модуля Cwd, который поставляется с Perl:
BEGIN {
use Cwd;
our $directory = cwd;
}
use lib $directory;
Вы можете сделать то же самое со значением $ 0, которое содержит имя сценария , Это может содержать относительный путь, но rel2abs может превратить его в абсолютный путь. Если у вас есть
BEGIN {
use File::Spec::Functions qw(rel2abs);
use File::Basename qw(dirname);
my $path = rel2abs( $0 );
our $directory = dirname( $path );
}
use lib $directory;
, модуль FindBin, поставляемый с Perl, может работать. Он находит каталог текущего запущенного скрипта и помещает его в $ Bin,
Я думаю, что алгоритмы стандартной библиотеки передают итераторы исключительно по значению (кто-то сейчас опубликует очевидное исключение из этого правила) - это может быть источником идеи. Конечно, ничто не говорит о том, что ваш собственный код должен выглядеть как Стандартная библиотека!
Во втором параметре объявления функции отсутствует ссылка, не так ли?
В любом случае, вернемся к вашему вопросу: нет, я никогда не читал ничего, что говорило бы, что вы не должны передавать итераторы мимо ссылка. Проблема со ссылками в том, что они позволяют вам изменять объект, на который указывает ссылка. В этом случае, если вы хотите изменить итератор, вы потенциально испортите всю последовательность за пределами этой точки, что сделает дальнейшую обработку невозможной.
Всего одно предложение: внимательно введите параметры.