I made a palindrome function that allows me to use any container type, and it worked for string, vector, and deque but when I made an STL list and tried running the code, but I get the error bellow and I couldn't figure out what that means and what to do.
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
Below the code I ran.
#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;
}
The standard container std::list has bidirectional iterators. The operator - used in this expression
itr1 = s.end() - 1
is defined for random access iterators. You could use instead the standard function std::prev
declared in the header <iterator>
like
itr1 = std::prev( s.end() )
However in any case the function is invalid because in general the user of the function can pass an empty container. In this case the expression std::prev( s.end() )
has undefined behavior.
And the operator < is not defined for bidirectional iterators. So this expression
itr < itr1
also may not be used in the function.
Moreover the function will not work with arrays because arrays do not have member functions like for example begin()
.
The function can look the following way as it is shown in the demonstrative program below.
#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;
}
The program output is
true
true
true
true
true
If you want you can specialize the function for random access iterators.