Почему я не могу использовать эту функцию палиндрома при использовании списка STL? - PullRequest
1 голос
/ 04 марта 2020

Я сделал функцию палиндрома, которая позволяет мне использовать любой тип контейнера, и она работала для строки, вектора и deque, но когда я составил список STL и попытался запустить код, но я получил ошибку ниже, и я не мог ' t понять, что это значит и что делать.

Severity    Code    Description Project File    Line    Suppression State
Error   C2676   binary '-': 'std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>' does not define this operator or a conversion to a type acceptable to the predefined operator homework4   C:\...\Source.cpp   9   

Severity    Code    Description Project File    Line    Suppression State
Error   C3536   'itr1': cannot be used before it is initialized homework4   C:\...\Source.cpp   9   

Severity    Code    Description Project File    Line    Suppression State
Error   C2676   binary '<': 'std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>' does not define this operator or a conversion to a type acceptable to the predefined operator homework4   C:\...\Source.cpp   9   
Severity    Code    Description Project File    Line    Suppression State
Error   C2100   illegal indirection homework4   C:\...\Source.cpp   10  

Список ошибок Visual Studio

Ниже кода, который я запустил.

#include <iostream>
#include<list>
#include<vector>
#include<deque>
using namespace std;

template <typename Container>
bool palindrome(const Container& s) {
    for (auto itr = s.begin(), itr1 = s.end() - 1; itr < itr1; itr++, itr1--) {
        if (*itr != *itr1)
            return false;
    }
    return true;
}

void main() {
    const string word1{ "racecar" };
    const vector<char> word2{ 'a', 'b', 'b', 'a' };
    const deque<int> word3{ 83, 84, 65, 84, 83 };
    const list<int> word4{ 83, 84, 65, 84, 83 };
    word4.end();

    cout << palindrome< string >(word1) << endl;
    cout << palindrome< vector<char> >(word2) << endl;
    cout << palindrome< deque<int> >(word3) << endl;
    cout << palindrome< list<int> >(word4) << endl;
}

1 Ответ

2 голосов
/ 04 марта 2020

Стандартный контейнер std :: list имеет двунаправленные итераторы. Оператор - используемый в этом выражении

itr1 = s.end() - 1

определен для итераторов с произвольным доступом. Вместо этого вы можете использовать стандартную функцию std::prev, объявленную в заголовке <iterator>, например

itr1 = std::prev( s.end() )

Однако в любом случае функция недопустима, поскольку в общем случае пользователь функции может передать пустой контейнер. В этом случае выражение std::prev( s.end() ) имеет неопределенное поведение.

И оператор <не определен для двунаправленных итераторов. Так что это выражение </p>

itr < itr1

также не может использоваться в функции.

Более того, функция не будет работать с массивами, поскольку массивы не имеют функций-членов, как, например, begin().

Функция может выглядеть следующим образом, как показано в демонстрационной программе ниже.

#include <iostream>
#include <iomanip>
#include <string>
#include <deque>
#include <vector>
#include <list>
#include <iterator>

template <typename Container>
bool palindrome( const Container &c ) 
{
    auto first = std::begin( c );
    auto last  = std::end( c );

    while ( first != last && first != --last && *first == *last ) ++first;      

    return first == last;
}

int main() 
{
    const std::string word1{ "racecar" };
    const std::vector<char> word2{ 'a', 'b', 'b', 'a' };
    const std::deque<int> word3{ 83, 84, 65, 84, 83 };
    const std::list<int> word4{ 83, 84, 65, 84, 83 };
    const char word5[] =  { 83, 84, 65, 84, 83 };

    std::cout << std::boolalpha << palindrome( word1 ) << '\n';
    std::cout << std::boolalpha << palindrome( word2 ) << '\n';
    std::cout << std::boolalpha << palindrome( word3 ) << '\n';
    std::cout << std::boolalpha << palindrome( word4 ) << '\n';
    std::cout << std::boolalpha << palindrome( word5 ) << '\n';

    return 0;
}

Вывод программы:

true
true
true
true
true

Если вы хотите, вы можете специализироваться функция для итераторов с произвольным доступом.

...