0

I am trying to create a very simple function:

bool is_palidrome(const std::string& s)
{
    std::string r(s.crbegin(), s.crend());
    return s==r;
}

In order to avoid unnecessary allocations I thought I could use a string_view:

bool is_palidrome(const std::string& s)
{
   std::string_view r(s.crbegin(), s.crend());
   return s==r;
}

However the last function fails to compile since the compiler cannot find a suitable constructor (I tried both g++ 12.2 and clang++ 15.0). Why there isn't a constructor for this case while std::string_view r(s.cbegin(), s.cend()); works perfectly? I check the standard https://en.cppreference.com/w/cpp/string/basic_string_view/basic_string_view but I do not see which condition is not satisfied.

9
  • 6
    A string_view is only ever over an existing contiguous buffer. How is it supposed to work? Commented Oct 6, 2022 at 16:12
  • 1
    One of the most common ways to check for a palindrome is to use a simple loop, indexing from both the beginning and the end, and compare individual characters until the indexes passes each other. It's actually going to be more effective than a comparison, because in a worst case (it's a palindrome) the comparison using == will compare the whole string, while a loop as described above will only compare half the string. Commented Oct 6, 2022 at 16:17
  • 1
    Regarding the [b,a] thing, that's not how computers work. The buffer needs to be contiguous in one direction (forward from a to b). You can't go backwards in space like that. Commented Oct 6, 2022 at 16:19
  • 3
    This is an XY Problem. You can implement is_palandrome without allocating. "Using std::string_view with reverse iterators" is not the solution, however. Commented Oct 6, 2022 at 16:25
  • 1
    @Someprogrammerdude -- well, it will actually compare the whole string, but using only Length / 2 iterations comparing 2-characters per-iteration :) Commented Oct 6, 2022 at 16:58

2 Answers 2

3

First it is better to have argument as std::string_view (so literals and std::string are covered without any extra allocations).

Then you need to check only half of the range and use algoritm std::equal (as in other answer).

bool is_palidrome(std::string_view s)
{
    return std::equal(begin(s), begin(s) + size(s) / 2, rbegin(s));
}

Note ADL allows to skip some std::.

Sign up to request clarification or add additional context in comments.

Comments

2

You don't need std::string_view to do this.

To implement your approach - comparing the entire string with its reverse - you can use std::equal.

bool is_palindrome(const std::string& s)
{
    return std::equal( begin(s), end(s), rbegin(s) );
}

2 Comments

Note this code is comparing the entire string, when really you only need to compare half of the string
@RemyLebeau absolutely correct. Marek R's answer changes what OP was attempting, and makes the function better in two ways.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.