Разбивая это, я вижу одну ошибку компилятора и одно предупреждение (логическая ошибка) и одну логическую ошибку, не обнаруженную компилятором.Сначала давайте разберемся с ошибкой.
В
for(vector<int>::iterator iterator = begin; iterator != end;)
vector<int>::iterator iterator = begin
пытается сделать vector<int>::iterator
из vector<int>::const_iterator
.Простое исправление:
for(vector<int>::const_iterator iterator = begin; iterator != end;)
Но begin
было передано в функцию по значению .Это означает, что вы можете делать все, что хотите, внутри функции, не затрагивая ее вне функции.Это означает, что создание переменной iterator
вовсе не обязательно.
for(/*do nothing here*/; begin != end;)
достаточно для устранения ошибки.Это приводит к логической ошибке.
for(vector<int>::iterator iterator = begin; iterator != end;)
и улучшенная версия
for(/*do nothing here*/; begin != end;)
ничего не делают для продвижения итератора, чтобы цикл выглядел более чем на первое значение.
for(/*do nothing here*/; begin != end; ++begin)
занимаетпозаботьтесь об этом.
Это оставляет нам только предупреждение компилятора.Никогда не игнорируйте предупреждения.Программисты, как правило, ленивы и одержимы скоростью.Они не пойдут на это и не понизят производительность печати сообщения, если это не означает что-то важное.Ошибка компилятора означает, что синтаксис неправильный и код не может быть превращен в программу.Предупреждение компилятора означает, что синтаксис правильный, и, при отсутствии других ошибок, код можно превратить в программу, но программа, вероятно, не является логически правильной.Никогда не игнорируйте предупреждения.Устраните их, где это возможно.Если они не могут быть устранены, докажите, что вы получаете поведение, которое вам требуется, и оправдывайте их.Только не игнорируйте их.
Предупреждение должно быть примерно таким: функция find
не возвращает значение на всех путях.
Примечание: я настроилкод стиль отступа Allman .Я считаю, что размещение фигурных скобок и чрезвычайно регулярный поток позволяет легко обнаружить неуместные или отсутствующие скобки и ошибки определения объема.Если у вас есть проблемы с синтаксисом, этот стиль устраняет возможные источники путаницы и позволяет сосредоточиться на других проблемах.
vector<int>::const_iterator find(vector<int>::const_iterator begin,
vector<int>::const_iterator end,
int num)
{
for(/*do nothing here*/; begin != end; ++begin)
{
if (*begin== num)
{
return begin;
}
else
{
return end;
}
}
}
Оба оператора return
находятся внутри цикла for
.Если begin == end
в начале, цикл for
никогда не войдет и функция выйдет без действительного return
.Результаты выхода из функции, объявленной для возврата значения без возврата значения, не определены.Программа может делать все что угодно, в том числе выглядеть так, как будто она работает.
На самом деле это указывает на то, что return end;
не там, где вы хотите.Он должен быть размещен после того, как все значения были проверены и признаны несоответствующими.Другими словами, вне цикла.Это делает корпус else
пустым и бесполезным.Удалите его.
Это оставляет
vector<int>::const_iterator find(vector<int>::const_iterator begin,
vector<int>::const_iterator end,
int num)
{
for(/*do nothing here*/; begin != end; ++begin)
{
if (*begin == num)
{
return begin;
}
}
return end;
}
, который можно улучшить для краткости, но я полагаю, что в результате получается наиболее понятный код.Короткий код - это хороший, но легко читаемый код, который компилятор преобразует в ту же программу, что и более короткий код, на мой взгляд, более ценный.
Sidenote:
Это рискованноприсвойте переменной то же имя, что и ее типу.
vector<int>::iterator iterator
безопасен, потому что имя типа - vector<int>::iterator
, а не просто iterator
, но обычная ранняя ошибка выглядит примерно так:
string string;
string name; // inscrutable error message here.
string
, переменная типа string
, принимает имя string
, делая string
тип недоступным, когда string
снова используется string name
.Плохой компилятор думает, что ему велено сделать переменную типа, который является другой переменной.Это также отличный пример Почему «использование пространства имен std» считается плохой практикой? std::string string;
сделает всю проблему невозможной, по крайней мере для типов в пространстве имен std
.