no matching function transform?
Hi all,
I followed the following post: http://www.codeguru.com/forum/showthread.php?t=472216 and try to test strlwr function. The test code is
Code:
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
int main (int argc, char * const argv[]){
string str = "Hello";
transform(str.begin(), str.end(), str.begin(), tolower);
cout << str << endl;
return 0;
}
but it seems that either my compiler does not have "transform" or I am missing something there, because when I compiled it, I got error
Code:
$ g++ -g -Wall strToLower.cpp -o strToLower
strToLower.cpp: In function ‘int main(int, char* const*)’:
strToLower.cpp:9: 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::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)’
Anybody helps please!
Thanks,
D.
Re: no matching function transform?
You didn't include <cctype>. That is where the tolower() declaration is located.
Regards,
Paul McKenzie
Re: no matching function transform?
Quote:
Originally Posted by
Paul McKenzie
You didn't include <cctype>. That is where the tolower() declaration is located.
Regards,
Paul McKenzie
Thanks Paul. I added that and I still have error :(
Code:
$ cat strToLower.c
#include <algorithm>
#include <string>
#include <iostream>
#include <cctype>
using namespace std;
int main (int argc, char * const argv[]){
string str = "Hello";
transform(str.begin(),str.end(),str.begin(),tolower);
cout << str << endl;
return 0;
}
$ g++ -g -Wall strToLower.c -o strToLower
strToLower.c: In function ‘int main(int, char* const*)’:
strToLower.c:10: 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::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)’
Re: no matching function transform?
Quote:
Originally Posted by
dukevn
Thanks Paul. I added that and I still have error
The program compiles correctly using Comeau.
If you changed the extension of the source file to .cpp instead of .c, what happens? What version of g++ are you using?
Regards,
Paul McKenzie
Re: no matching function transform?
Quote:
Originally Posted by
Paul McKenzie
The program compiles correctly using Comeau.
If you changed the extension of the source file to .cpp instead of .c, what happens? What version of g++ are you using?
Thanks Paul for your prompt reply. Here is the output:
Code:
$ mv strToLower.c strToLower.cpp
$ g++ -g -Wall strToLower.cpp -o strToLower
strToLower.cpp: In function ‘int main(int, char* const*)’:
strToLower.cpp:10: 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::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)’
$ g++ --version
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5490)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I just also tried on my remote Red Hat server, and I got error as well:
Code:
$ g++ -g -Wall strToLower.cpp -o strToLower
strToLower.cpp: In function 'int main(int, char* const*)':
strToLower.cpp:10: 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::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded function type>)'
$ g++ --version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Re: no matching function transform?
It looks like you have a bad install, your #include path is not correct, or the compiler just doesn't have that function (which is hard to believe).
If you opened the <algorithm> file, do you see a transform function there? If you do, can you post the declaration of it (it will be a template function, so all we want is the declaration, not the entire body of the function).
Regards,
Paul McKenzie
Re: no matching function transform?
Well, the problem is that the version of std::tolower inherited from the C standard library is a non-template function, but there are other versions of std::tolower that are function templates, and it is possible for them to be included depending on the standard library implementation. You actually want to use the non-template function, but there is ambiguity when just tolower is provided as the predicate.
One workaround is to qualify the name since the non-template function may be available in the global namespace:
Code:
transform(str.begin(), str.end(), str.begin(), ::tolower);
But it may be better to define a wrapper for tolower that actually takes a char argument and returns a char (the version inherited from C takes an int argument and returns an int).
Re: no matching function transform?
Quote:
Originally Posted by
laserlight
Well, the problem is that the version of std::tolower inherited from the C standard library is a non-template function, but there are other versions of std::tolower that are function templates, and it is possible for them to be included depending on the standard library implementation.
OK, that sounds right -- I now see the
<unknown type>
error for the last argument in transform.
Regards,
Paul McKenzie
Re: no matching function transform?
Quote:
Originally Posted by
laserlight
Code:
transform(str.begin(), str.end(), str.begin(), ::tolower);
Adding "::" solved the problem. Thank you very much for your help, Paul and laserlight.
Re: no matching function transform?
Quote:
Originally Posted by
dukevn
Adding "::" solved the problem. Thank you very much for your help, Paul and laserlight.
Sorry Paul, would you mind trying the code with "::" added? The reason I ask is because if that does not work with your compiler (Corneau), then I really doubt the portability of C++ code!
Thanks.
Re: no matching function transform?
Quote:
Originally Posted by dukevn
Sorry Paul, would you mind trying the code with "::" added? The reason I ask is because if that does not work with your compiler (Corneau), then I really doubt the portability of C++ code!
You can test with the online Comeau compiler.
However, as I implied, there is no guarantee that the non-template version of tolower will be available in the global namespace (unless you #include <ctype.h> instead). A really portable solution is to write a wrapper, e.g.,
Code:
inline char charToLower(char c)
{
return std::tolower(c);
}
// ...
transform(str.begin(), str.end(), str.begin(), charToLower);
Re: no matching function transform?
Quote:
Originally Posted by
laserlight
Thanks for the link. I tried both with and without "::" and they both worked.
Quote:
Originally Posted by
laserlight
However, as I implied, there is no guarantee that the non-template version of tolower will be available in the global namespace (unless you #include <ctype.h> instead). A really portable solution is to write a wrapper, e.g.,
Code:
inline char charToLower(char c)
{
return std::tolower(c);
}
// ...
transform(str.begin(), str.end(), str.begin(), charToLower);
Yeah, this one is much better. By the way, I tried also with and without "inline" and they both worked. Do I really need that "inline"?
Thanks,
D.
Re: no matching function transform?
Quote:
Originally Posted by
dukevn
Thanks for the link. I tried both with and without "::" and they both worked.
Yeah, this one is much better. By the way, I tried also with and without "inline" and they both worked. Do I really need that "inline"?
Not really. It's used as a request to the compiler to inline the code, but the actual inlining doesn't have to be granted.
Regards,
Paul McKenzie
Re: no matching function transform?
Quote:
Originally Posted by
Paul McKenzie
Not really. It's used as a request to the compiler to inline the code, but the actual inlining doesn't have to be granted.
Regards,
Paul McKenzie
Thanks Paul.