#cpp #алгоритм #вектор
Здравствуйте вот есть код, вроде написан правильно, пишу на CodeBlocks: #include#include #include using namespace std; template elemType& min (const std::vector &vec) { typename std::vector ::iterator select = vec.begin(), it = next(select), end_it = vec.end(); for ( ; it != end_it; it++ ) { if ( *it < *select ) select = it; } return *select; }; int main() { int massiv[10] = {35, 66, 98, 15, 32, 41, 24, 90, 55, 100}; std::vector vec_train(massiv,massiv+10); min(vec_train); return 0; } Но выдает следующую ошибку: error: conversion from 'std::vector::const_iterator {aka __gnu_cxx::__normal_iterator >}' to non-scalar type 'std::vector::iterator {aka __gnu_cxx::__normal_iterator >}' requested| Как такие ошибки вообще расшифровывать самостоятельно, если я только недавно начал учить программирование? Спасибо.
Ответы
Ответ 1
В функции параметр определен как константная ссылка elemType& min (const std::vector&vec) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Поэтому такие функции, как begin и end возвращают итератор типа const_iterator. Исправьте typename std::vector ::const_iterator select = vec.begin(), it = next(select), end_it = vec.end(); Также вам следует включить заголовок #include так как в программе используется функция std::next, объявленная в этом заголовке. Также имейте в виду, что функция min некорректна, так как в общем случае переданный вектор может быть пустым. А это значит, что в функции имеет место обращение к не существующему элементу вектора и, соответственно, разыменование недействительного итератора. Имеется стандартный алгоритм std::min_element, объявленный в заголовке , который выполняет поставленную задачу. Ваша функция может быть определена по аналогии с этим алгоритмом. Например, #include #include template auto min( const std::vector &vec ) { auto select = vec.begin(); if ( select != vec.end() ) { for ( auto it = vec.begin(), end_it = vec.end(); ++it != end_it; ) { if ( *it < *select ) select = it; } } return select; } int main() { int massiv[] = { 35, 66, 98, 15, 32, 41, 24, 90, 55, 100 }; const size_t N = sizeof( massiv ) / sizeof( *massiv ); std::vector vec_train( massiv, massiv + N ); auto it = min( vec_train ); if ( it != vec_train.end() ) { std::cout << "Minimum is " << *it << std::endl; } return 0; } Вывод прогоаммы на консоль Minimum is 15 Если ваш компилятор не поддерживает спецификатор типа auto, то функцию можно определить как template typename std::vector ::const_iterator min( const std::vector &vec ) { typedef typename std::vector ::const_iterator const_iterator; const_iterator select = vec.begin(); if ( select != vec.end() ) { for ( const_iterator it = vec.begin(), end_it = vec.end(); ++it != end_it; ) { if ( *it < *select ) select = it; } } return select; } Ответ 2
error: conversion from 'std::vector::const_iterator {aka __gnu_cxx::__normal_iterator >}' to non-scalar type 'std::vector::iterator {aka __gnu_cxx::__normal_iterator >}' requested Как такие ошибки вообще расшифровывать самостоятельно, если я только недавно начал учить программирование? Для начала, из текста ошибки надо выкинуть всё лишнее. В данном случае убрать текст в фигурных скобках вместе со скобками. Он ссылается на внутренний для компилятора тип итератора. "aka" означает "also known as", т.е. по сути, синоним, альтернативное имя. Получим: error: conversion from 'std::vector::const_iterator' to non-scalar type 'std::vector::iterator' requested Здесь уже более чётко видно о чём говорит ошибка: запрошено преобразование из 'std::vector::const_iterator' в нескалярный тип 'std::vector::iterator' Скалярный тип это в частности любой арифметический тип, например, double или int. Между такими типами в c++ предусмотрены неявные преобразования. Т.е. можно написать, скажем: double d = 5.5; int i = d; и компилятор не выдаст на это никаких ошибок. В Вашем случае, тип нескалярный, а значит для неявного преобразования из одного типа T1 в другой T2 должен быть определён: либо конструктор для типа T2, принимающий аргумент типа T1; либо оператор преобразования в типе Т1 вида operator T2(). Преобразования std::vector::const_iterator в std::vector::iterator не существует (хотя стоит заметить, что есть обратное преобразование), поэтому компилятор и выдал соответствующую ошибку. Ну, а про устранение причины ошибки уже подробно расписано в другом ответе, поэтому не вижу смысла повторяться.
Комментариев нет:
Отправить комментарий