Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable unwanted overload for tolower

Tags:

c++

c++11

While researching, I found Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully? , and the solution is to use ::tolower. As an exercise, I want to see if I can disable that (in locale header file) overload and use std::tolower. First, we start simple:

template <typename charT> charT tolower(charT c, std::locale const& loc) = delete;

int main()
{
    std::vector<char> chars = { 'a', 'D', 'c', 'b' };
    std::transform(chars.begin(), chars.end(), chars.begin(), std::tolower);
}

The compiler cannot deduce the correct overload. So we provide the char template:

std::transform(chars.begin(), chars.end(), chars.begin(), std::tolower<char>);

So we're back to square one. I know it is undefined behavior, but I thought I could put it into namespace std:

namespace std {
template <typename charT> charT tolower(charT c, std::locale const& loc) = delete;
}

Now the compiler says I'm redefining the function.

using std::tolower;
template <typename charT> charT tolower(charT c, std::locale const& loc) = delete;

doesn't work either.

Now this is pointless exercise, but is this possible?

like image 841
user4320030 Avatar asked Jan 17 '26 15:01

user4320030


1 Answers

You can't disable the other overload, but there are lots of ways to ensure the correct one is chosen:

int (*lower)(int) = std::tolower;
std::transform(chars.begin(), chars.end(), chars.begin(), lower);

or

std::transform(chars.begin(), chars.end(), chars.begin(), static_cast<int(*)(int)>(std::tolower));

or

std::transform(chars.begin(), chars.end(), chars.begin(), [](int c) { return std::tolower(c); });

or

struct ToLower {
  int operator()(int c) const { return std::tolower(c); }
};
std::transform(chars.begin(), chars.end(), chars.begin(), ToLower{});

The first two forms tell the compiler how to choose the right overload from the overload set, because only one of the overloads can be converted to a function pointer of that type.

The second two forms create a wrapper that invokes tolower so that normal overload resolution finds the right one, and you don't need to take the address of tolower.

like image 146
Jonathan Wakely Avatar answered Jan 20 '26 07:01

Jonathan Wakely



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!