To my surprise the following code compiles:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>
int main() {
std::string s="nawaz";
std::string S;
std::transform(s.begin(),s.end(), std::b开发者_高级运维ack_inserter(S), ::toupper);
std::cout << S ;
}
I had expected it to fail because of the ::toupper
which I believed should be in the std
namespace. A quick check of cctype shows that it is but it is imported from the root namesapce (Mystery solved there).
namespace std
{
// Other similar `using` deleted for brevity.
using ::toupper;
}
So first problem solved but if I change the transform()
line above too:
std::transform(s.begin(),s.end(), std::back_inserter(S), std::toupper);
I would now expect this to now also compile. But I get a compiler error:
kk.cpp:12: error: no matching function for call to `transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::cha r_traits<char>, std::allocator<char> > >, std::back_insert_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded function type>)'
Which with manual editing resolved too:
kk.cpp:12: error: no matching function for call to
`transform(iterator<std::string>,
iterator<std::string>,
std::back_insert_iterator<std::string>,
<unresolved overloaded function type>)'
What am I missing?
It doesn't work because there are overloads of std::toupper
. You can fix it by casting to your desired function overload:
std::transform(s.begin(),s.end(), std::back_inserter(S),
(int(&)(int))std::toupper);
You're missing that C++ also adds new toupper
functions in <locale>
which is probably included implicitly by one of your other headers. Thus in the std::
namespace there are multiple overloads while in the global namespace there is only the old C version of the function.
That said it does still seem like g++ should be able to deduce the correct overload.
Like others said the problem is that std::toupper and friends are overloaded. One way to fix this is to use a lambda.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
int main()
{
std::string s{ "This is a test" };
std::string S{};
std::transform(s.begin(), s.end(), std::back_inserter(S), [] (char ch){ return std::toupper(ch); });
std::cout << S;
return 0;
}
I realize this is an old post but as many, including myself, still encounter this issue, I hope my post will be helpful.
精彩评论