0

Hello I am very new to programming and C++. I'm trying to make a program that checks if a string is a palindrome (a word that is the same backwards as it is forwards).

In order to do that I searched online about how to reverse a string and came across the reverse(string.begin(), string.end()) function from <bits/stdc++.h>.

I've made a function that can reverse the string written in the parameters and it works fine:

#include <iostream>
#include <vector>
#include <string>
#include <bits/stdc++.h>

std::string reverseStr(std::string str) {
    reverse(str.begin(), str.end());
    
    return str;
} 

int main() {

    std::cout << reverseStr("word");

}

But when I want to assign the reversed string into a new variable "reversedStr":

#include <iostream>
#include <vector>
#include <string>
#include <bits/stdc++.h>

std::string reverseStr(std::string str) {
    std::string reversedStr;
    reversedStr = reverse(str.begin(), str.end());
    
    return reversedStr;
} 

int main() {

    std::cout << reverseStr("word");

}

Then when I try and compile it, it gives me this error.

C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/basic_string.h:776:7: note:   no known conversion for argument 1 from 'void' to 'std::initializer_list<char>'
The terminal process "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command g++ -g main.cpp" terminated with exit code: 1.

If you wouldn't mind explaining what is happening that would be great! Thank you!

Drew
  • 1
  • 1
  • Side note: [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) Instead you should `#include ` – Ranoiaetep Nov 16 '20 at 02:35

3 Answers3

4

reverse reverses a collection in place and doesn't return it. If you want to do it to a new variable, then first copy the string to the variable then reverse that:

// pass the str argument by reference to avoid unnecessary copies
std::string reverseStr(const std::string& str) {
    std::string reversedStr = str;
    std::reverse(reversedStr.begin(), reversedStr.end());
    return reversedStr;
} 
Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • 1
    Better yet use `std::reverse_copy` with a `std::back_inserter`. Maybe more advanced than necessary, but I wanted to be clever :( https://en.cppreference.com/w/cpp/algorithm/reverse_copy – JohnFilleau Nov 16 '20 at 02:38
  • 1
    @JohnFilleau it does not have to be that complicated, one liner `std::string reverseStr( str.rbegin(), str.rend() );` or that should be return statement in this case – Slava Nov 16 '20 at 04:22
  • 3
    "pass the str argument by reference to avoid unnecessary copies" very funny comment when the first thing you do is making a copy – Slava Nov 16 '20 at 04:24
  • 1
    It's more than just funny, it's actively bad. Pass by `const&` breaks the move-optimization. – MSalters Nov 16 '20 at 10:24
1

As stated in documentation std::reverse() does not return anything so you cannot assign it's return value to a variable. Simplest solution would be:

std::string reverseStr(const std::string &str) 
{
    return std::string( str.rbegin(), str.rend() );
} 

using reverse iterators to initialize and return temporary std::string

Slava
  • 43,454
  • 1
  • 47
  • 90
0

std::reverse() is used to reverse the elements within the range given by the two parameters, str.begin() and str.end() in your case. This does not return a new reversed string, instead it reverses the collection itself.

If you want the reversed content in a new variable, you must first copy the original string into a new string and then reverse the new string. Alternatively you could use std::reverse_copy() which copies the reverse contents to a new string without affecting the original. It takes in a third parameter that tells where the reversed content must be copied. Do note the reversed string variable must first be resized to the original string's size.

std::string reverseStr(std::string& str) {
    std::string reversedStr;
    reversedStr.resize(str.size());

    std::reverse_copy(str.begin(), str.end(), reversedStr.begin());
    return reversedStr;
}

Some additional info: std::reverse() and std::reverse_copy() are present in the <algorithm> header file. <bits/stdc++.h> is non-standard and compiler specific and hence should be avoided. Check this answer for more details: Why should I not #include <bits/stdc++.h>?

ATK
  • 47
  • 1
  • 8