Check if the string is palindrome The following code runs correctly:

#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;string&gt;

bool is_palindrom(const std::string&amp; str)
{
    std::string temp(str);
    std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
    return temp == std::string(temp.rbegin(), temp.rend());
}

int main()
{
    std::string str{ "KArak" };
    std::cout &lt;&lt; is_palindrom(str) &lt;&lt; std::endl;
    return 0;
}


Can I do this better? The constraint is to keep the declaration of the function the same and only change the implementation.
To the readers: I had to use ::tolower because the std:: version was causing compiler errors. I'm investigating this right now. The issue stems from std::tolower being overloaded. What is funny is that it is in header &lt;locale&gt;, which means that the standard library implementation includes it in some way. Rakete1111 proposed lambda version, which works great.

Yes. 

Use more standard library:

The std::string provides reverse iterators, so there is no need to do any copy at all. In fact, it is possible to it with indices, but it won't look that pretty:

    return std::equal(str.cbegin(), str.cbegin() + str.size() / 2, str.crbegin(), 
                      [](unsigned char lhs, unsigned char rhs) {
                          return std::tolower(lhs) == std::tolower(rhs);
                      });


The actual version was different, thanks to Rakete1111 for a new version. There is a note in the comments from Loki and Jerry: it seems like using functions in &lt;cctype&gt; are dangerous and will result in undefined behavior unless the input is cast into unsigned char first.

It is also possible to refactor the ugly + str.size() / 2 into reusable function:

#include &lt;iterator&gt;

//some namespace
template &lt;typename Container&gt;
constexpr auto mid(const Container&amp; container)
{
    auto half_distance = std::distance(std::begin(container), 
                                       std::end(container)) / 2;
    return std::next(container.begin(), half_distance);
}


Then it transforms into:

bool is_palindrome(const std::string&amp; str) {
    return std::equal(str.cbegin(), mid(str), str.crbegin(), 
                      [](unsigned char lhs, unsigned char rhs) {
                          return std::tolower(lhs) == std::tolower(rhs);
                      });
}


Other things that could be done better:


Avoid std::endl. It can cause big performance issues.
There is a typo in the word palindrome. 
std::boolalpha could be used to provide more user friendly output.
more unit tests.
It seems like the code is missing &lt;cctype&gt; header as well.
putting everything into a namespace. Absence of it will force users to do unqualified call, which is prone to ADL, which is sometimes very evil.


Put together:

#include &lt;iomanip&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;string&gt;
#include &lt;cctype&gt;
#include &lt;iterator&gt;

//some namespace
template &lt;typename Container&gt;
constexpr auto mid(const Container&amp; container)
{
    auto half_distance = std::distance(std::begin(container), 
                                       std::end(container)) / 2;
    return std::next(container.begin(), half_distance);
}

bool is_palindrome(const std::string&amp; str) {
    return std::equal(str.cbegin(), mid(str), str.crbegin(), 
                      [](unsigned char lhs, unsigned char rhs) {
                          return std::tolower(lhs) == std::tolower(rhs);
                      });
}

int main()
{
    std::string str{ "KArak" };
    std::cout &lt;&lt; std::boolalpha;
    std::cout &lt;&lt; "is \"KArak\" palindrome? " &lt;&lt; is_palindrome(str) &lt;&lt; '\n';
    std::cout &lt;&lt; "is \"fuf\" palindrome? " &lt;&lt; is_palindrome("fuf") &lt;&lt; '\n';
    std::cout &lt;&lt; "is empty string palindrome? " &lt;&lt; is_palindrome("") &lt;&lt; '\n';
    return 0;
}


Live demo.