Std::Transform() and Toupper(), No Matching Function

std::transform() and toupper(), no matching function

Just use ::toupper instead of std::toupper. That is, toupper defined in the global namespace, instead of the one defined in std namespace.

std::transform(s.begin(), s.end(), std::back_inserter(out), ::toupper);

Its working : http://ideone.com/XURh7

Reason why your code is not working : there is another overloaded function toupper in the namespace std which is causing problem when resolving the name, because compiler is unable to decide which overload you're referring to, when you simply pass std::toupper. That is why the compiler is saying unresolved overloaded function type in the error message, which indicates the presence of overload(s).

So to help the compiler in resolving to the correct overload, you've to cast std::toupper as

(int (*)(int))std::toupper

That is, the following would work:

//see the last argument, how it is casted to appropriate type
std::transform(s.begin(), s.end(), std::back_inserter(out),(int (*)(int))std::toupper);

Check it out yourself: http://ideone.com/8A6iV

C++ Error: no matching function for call to 'toupper'


  1. You need to include the appropriate headers, in this case <string> and <cctype>.
  2. You need to specify the namespaces, in this case std:: (use say using namespace std, but that is not a good idea).
  3. it is not a character. It is an iterator into the string. Think of it as a pointer-like object. When you want to change a character pointed to by p, you would say *p = do_something_with(*p), not p = do_something_with(p) which would change the pointer.

Thus if we write:

#include <iostream>
#include <cctype>

int main()
{
std::string s("some string");
if (s.begin() != s.end()) {
auto it = s.begin();
*it = std::toupper(*it);
}
}

then this compiles (GodBolt.org).

C++ std::transform() and toupper() ..why does this fail?

There is no space in out. C++ algorithms do not grow their target containers automatically. You must either make the space yourself, or use a inserter adaptor.

To make space in out, do this:

out.resize(s.length());

[edit] Another option is to create the output string with correct size with this constructor.

std::string out(s.length(), 'X');

convert a string into uppercase but getting error?

Your code is mixing C++ strings and C-style char * strings. s.c_str() may work, but can't be guaranteed in this case. convertToUpper(s.c_str()) is going to modify the array returned by c_str() and C++ gives no assurances that this will behave the way you want. The next problem will be passing the char * returned by convertToUpper into dataHolderMap.find, which is expecting a string, not a char *.

Best to keep the string a string.

Unless you have a need to preserve the input string s, take a good look at std::transform. If you need to preserve s, make a copy first and run transform on the copy.

std::transform(s.begin(), s.end(), s.begin(), ::toupper);

Will do the conversion you want and keep the string a string so that the call to dataHolderMap.find() gets the string it needs.

#include <algorithm> 
...

std::string uppercase = s;
std::transform(uppercase.begin(), uppercase.end(), uppercase.begin(), ::toupper);
std::map<std::string, Code>::iterator it = dataHolderMap.find(uppercase);

Alternative is to use the Boost library in place of transform. Warning: Boost can be a pretty expensive hammer if you don't already have it installed and configured.

#include <boost/algorithm/string.hpp>
...

std::map<std::string, Code>::iterator it = dataHolderMap.find(boost::to_upper_copy(s));

Convert string to all uppercase leters with std::transform

Use ostream_iterator<char> instead of ostream_iterator<string>:

transform(s.begin(),s.end(),ostream_iterator<char>(cout,"\n"),std::toupper);

std::transform transforms each character and pass it to the output iterator. That is why the type argument of the output iterator should be char instead of std::string.

By the way, each character will be printed on a newline. Is that what you want? If not, don't pass "\n".

--

Note : You may have to use ::toupper instead of std::toupper.

See these

  • http://www.ideone.com/x6FB5 (each character on a newline)
  • http://www.ideone.com/RcEKn (all characters on the same line)

Converting German Letters to Uppercase won't work

You are searching for uppercase letters and replacing them with lowercase letters.

If you want to make the letters to uppercase, you have to do the opposite.

string makeUpperCase(string c)
{
transform(c.begin(), c.end(), c.begin(), ::toupper);
while(c.find("ä") != string::npos)
{
c.replace(c.find("ä"), 2, "Ä");
}
while(c.find("å") != string::npos)
{
c.replace(c.find("å"), 2, "Å");
}
while(c.find("ö") != string::npos)
{
c.replace(c.find("ö"), 2, "Ö");
}

return c;
}


Related Topics



Leave a reply



Submit