Reputation: 700
I'm trying to utilize the following answer: String To Lower/Upper in C++ but I'm using C++17, which means the answer is deprecated.
Replacing bind1st
with bind
was trivial, now I'd like to replace mem_fun
with mem_fn
, but for some reason it's not so simple for me.
I tried the following replacement:
auto greet = std::mem_fn<wchar_t(wchar_t)>(&ctype<wchar_t>::toupper);
Which gives me the "no matching overloaded function found" error. Why? How could I solve it if I wanted to stick to std::transform
?
Upvotes: 0
Views: 899
Reputation: 303890
The correct spelling is:
auto greet = std::mem_fn<wchar_t(wchar_t) const, std::ctype<wchar_t>>(
&std::ctype<wchar_t>::toupper);
or actually you don't need both template parameters, just the first one:
auto greet = std::mem_fn<wchar_t(wchar_t) const>(&std::ctype<wchar_t>::toupper);
The important part you're missing is the const
: it's a const
member function, and you need the full type.
But you're better off writing the lambda:
auto greet = [](std::ctype<wchar_t> const& ct, wchar_t c) {
return ct.toupper(c);
};
Upvotes: 3
Reputation: 26194
It is simpler to avoid std::bind
, std::mem_fn
and friends, and use lambdas instead.
For instance:
std::transform(in.begin(), in.end(), out.begin(), [&ct](wchar_t c) {
return ct.toupper(c);
});
Upvotes: 3
Reputation: 10614
As you can see in std::mem_fn
declaration, there are two template parameters, the first one is the function signature, and the second one is the class type. The problem is that you only explicitly specified function signature and not the class type, which makes the compiler have to deduce it from the argument. And the argument is an overload set std::ctype<wchar_t>::toupper
, which you did not resolve with a cast.
The fix is to explicitly cast the std::ctype<wchar_t>::toupper
pointer to the member pointer you want. After that you don't need to explicitly specify the template parameter of std::mem_fn
.
using toupper_t = wchar_t (std::ctype<wchar_t>::*)(wchar_t) const;
auto greet = std::mem_fn(static_cast< toupper_t >(&std::ctype<wchar_t>::toupper));
But, of course, it is much easier to just use a lambda instead.
Upvotes: 3