Disable unwanted overload for tolower

While researching, I found Why "transform (s.begin (), s.end (), s.begin (), tolower)" cannot be executed successfully? and the solution is to use ::tolower

. As an exercise, I want to see if I can disable this (in the locale header file) overload and use std::tolower

. First, we start simply:

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 output the correct overload. Therefore, we provide a char template:

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

      

So we are back to square one. I know this is undefined behavior , but I thought I could put it in the std namespace:

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

      

Now the compiler says that I am overriding the function.

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

      

doesn't work either.

Now this is a pointless exercise, but is it possible?

+3


source to share


1 answer


You cannot disable another overload, but there are many ways to ensure the correct choice is made:

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 select the correct 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 calls tolower

, so that normal overload resolution finds the correct one and you don't need to take the address tolower

.

+5


source







All Articles