I try to write a program check a string is Palindrone or not using vector and iterator.
I create definition in iterator.h file:-
#pragma once
#ifndef iterator
#define iterator
template<typename Bidrectional>
bool isPalindrone(Bidrectional first, Bidrectional end);
template<typename Bidrectional>
inline bool isPalindrone(Bidrectional first, Bidrectional last)
{
while (true)
{
last--;
if (first == last)
break;
if (*first != *last)
return false;
first ;
if (first == last)
{
break;
}
return true;
}
}
#endif
Now I got so many error in compile time:-
Severity Code Description Project File Line Source Suppression State
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1640 Build
Error C2976 'std::reverse_iterator': too few template arguments c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 656 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 906 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 939 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 943 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 947 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1170 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1186 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1563 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1583 Build
Error C2059 syntax error: '=' c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 654 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1650 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 2039 Build
Error C4430 missing type specifier - int assumed. Note: C does not support default-int c project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 2035 Build
In main function I call is
#include <iostream>
#include "iterator.h"
#include <vector>
using namespace std;
int main()
{
vector<string> s1;
s1.push_back("Otto");
isPalindrone(s1.begin(), s1.end());
}
I am new to STL, Could you please help in this regards.
CodePudding user response:
The problem is this line from the header file:
#define iterator
From that point onward, all mentions of the symbol iterator
will be that macro. And it will expand to nothing.
So when e.g. std::vector
defines its iterator
type, it can't.
For header include guards use more complex names. Even using all upper-case (which is what most people uses for macros) would be enough.
Since your header file name is iterator.h
(which is really a bad and misleading name) I suggest something like ITERATOR_H
instead.
CodePudding user response:
Initial Problem
You've #define iterator
meaning that everywhere that the symbol iterator
is used it is replaced with, well nothing but this essentially deleted the symbol iterator everywhere it's used meaning that vector and string can't find their iterator types. Try using a different name for the header guard and all capital letters is ideal by convention for macros. Also try giving the header a more complex name as iterator is too generic and could cause future errors. isPalindrone.h
would be better.
Eg.
#ifndef IS_PALINDRONE_H
#define IS_PALINDRONE_H
/// ...
#endif
- credit @Some programmer dude
Main Question
As for the main part of you're code, using a std::vector<std::string>>
. This means that the iterator returned from s1.begin()
and s1.end()
are iterators to std::string
types, not to the elements of the string, ie. the characters of the string. This means that, for example s1.begin()
actually returns an iterator to a std::string
with the value "Otto"
not to a character 'O'
like I assume you want.
std::vector
is C 's dynamic array type as opposed to std::string
which (as the name suggests) is the most basic string type in C .
You have two options to fix this. First std::string
has iterators of its own which you can pass to you're isPalindrone()
function as it stands, or you can create a std::vector<char>
and push back each character. This vectors iterators will point to the elements in the vector, ie. iterators to chars
. I would personally use a std::string
as its easier to manage string types this way but both options work if you were to expand beyond words to say numbers maybe.
Using std::vector<char>
Here's a quick way to make a string into an array of characters.
#include <algorithm>
#include <iterator>
std::string s1 = "otto";
std::vector<char> vs(4); ///< The 4 here is used to pre-allocate memory
std::copy(s1.begin(), s1.end(), std::back_inserter(vs)) ///< Pushes the elements of s1 to the back of vs
Alternative
I know you might be trying to learn iterators and algorithm patterns in C but if you want an alternative to approach to achieve the same task, is you can use the std::equal
algorithm (found in the <algorithm>
header) and std::string
's reverse iterators (the .rbegin()
and .rend()
methods).
#include <algorithm>
#include <string>
/// templated for different string types. Can restrict using concepts (look below)
template<typename StringT>
inline bool isPalindrone(StringT str)
{ return std::equal(str.begin(), str.end(), str.rbegin(), str.rend()); }
Quick Fix for isPalindrone()
One thing you forget to do in you're implementation of isPalindrone()
is you don't decrement the end
iterator each iteration. By decrementing end
each loop you move backwards through the letters of the word, comparing each letter from the front forwards to the back backwards. It also should be noted that anything using templates in C must be in a header so the function isPalindrone()
must all be in a header.
# First Loop
first
v
Otto
^ end
# Second Loop
first
v
Otto
^ end
Updated Code
template<typename Bidrectional>
inline bool isPalindrone(Bidrectional first, Bidrectional last)
{
while (true)
{
last--;
if (first == last)
break;
if (*first != *last)
return false;
first ;
end--; ///< Decrement `end`
return true;
}
}
Links and Resources
I mentioned a lot so here are links to everything I used to answer the question.
- std::vector : cppreference
- std::string : cppreference
- Note, the link for
std::string
links tostd::basic_string
because it is used to implement all standard string types in C . Scroll down a bit for details.
- Note, the link for
- Iterators Library : cppreference
- std::equal : cppreference
- std::copy :cppreference
- std::back_inserter : cppreference
- Concepts Library (if interested) : cppreference Useful to constrain template parameters
If there is anything I missed; edits and constructive comments to help improve the answer would be appreciated.