0

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   

Error picture:- enter image description here

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.

Sangita Paul
  • 107
  • 7
  • Does this answer your question? [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – paolo Aug 09 '22 at 08:19
  • Don't `#include` a `.cpp` file in a header file. – Peter Aug 09 '22 at 08:19
  • 1
    `iterator.cpp` includes `iterator.h` which includes `iterator.cpp`... You don't see this as a possible problem? And where is the `#endif // iterator` in your `iterator.h` file? – Some programmer dude Aug 09 '22 at 08:20
  • Ok I can remove iterator.cpp from iterator.h file.but error is still there – Sangita Paul Aug 09 '22 at 08:22
  • Foo.h template struct Foo { void doSomething(T param); }; #include "Foo.tpp" Foo.tpp template void Foo::doSomething(T param) { //implementation }.....I follow this concept – Sangita Paul Aug 09 '22 at 08:25
  • No, you need to remove `#include "iterator.h"` from `iterator.cpp` . – G.M. Aug 09 '22 at 08:25
  • Yes I already did – Sangita Paul Aug 09 '22 at 08:25
  • Error gives me in vector.cpp file – Sangita Paul Aug 09 '22 at 08:28
  • Please create one single source file containing all your code, and show it to us. The copy-paste the full and complete *build log* as text into the question as well. – Some programmer dude Aug 09 '22 at 08:32
  • @ Some programmer dude, okye then I declear it in header file with inline – Sangita Paul Aug 09 '22 at 08:34
  • @ Some programmer dude, ok I did, I edit in my question – Sangita Paul Aug 09 '22 at 08:47
  • 1
    Please try to create a proper [mre] to show us. A *single* source file, with all `#include` directives needed to build, and with a `main` function. We are missing quite lot from the "main" source file as it is right now, there's no way we can replicate the error. And on its own the `isPalindrone` function seems like it should work which means the error is somewhere else. – Some programmer dude Aug 09 '22 at 09:02
  • #include //#include "AllHeader.h" #include "iterator.h" #include "Point.h" #include "list.h" #include #include using namespace std; int main() { vector s1; s1.push_back("Otto"); isPalindrone(s1.begin(), s1.end()); } – Sangita Paul Aug 09 '22 at 09:42
  • When I put #include in my main function , then only I got this error...why? – Sangita Paul Aug 09 '22 at 09:45
  • Don't put code in comments. Instead use the [edit] facility to update your question and provide a [mcve] (as already requested several times previously). – G.M. Aug 09 '22 at 09:52
  • I just [can't replicate your problem](https://godbolt.org/z/bW9hYYPPE) using either GCC, Clang or MSVC. The only problem is that misplaced `return true;` in `isPalindrone`. But you seem to include quite a lot of non-standard header files. Are you sure the error isn't on one of them? – Some programmer dude Aug 09 '22 at 09:56
  • @Some programmer dude https://github.com/BUBAIMITRA2018/iterator.git – Sangita Paul Aug 09 '22 at 10:34

3 Answers3

2

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

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.

If there is anything I missed; edits and constructive comments to help improve the answer would be appreciated.

oraqlle
  • 186
  • 2
  • 12
0

Little modification @oraqlle solution:-

    std::string s1 = "otto";
std::vector<char> vs(4);  ///< The 4 here is used to pre-allocate memory


std::copy(s1.begin(), s1.end(), vs.begin());

for (auto v : vs)
{
    cout << v << "\t";
}

bool a = isPalindrone(vs.begin(), vs.end());
Sangita Paul
  • 107
  • 7