1

I have this weird error where the code was working before but after some time it stopped compiling. The error is:

Could not find a match for 'std::transform<InputIterator,OutputIterator,UnaryOperation>(char *,char *,char *,charT (*)(charT,const locale &))' in function main() 

and the lines which it is referring to is:

    string ans;
    cin>>ans;
    std::transform(ans.begin(), ans.end(), ans.begin(), ::tolower);

Can someone please help me out as to why this is happening? The includes I used were:

#include <fstream.h>;
#include <iostream.h>;
#include <string>;
#include <time.h>;
#include <vector>;
using namespace std;

Thank you very much

  • It says that your trying to pass a `char *` as an iterator, you should take a look at the `std::transform` & `string` doc – Thomas Ayoub Jul 03 '13 at 06:58
  • 1
    @Samoth What's wrong with using a pointer as an iterator? – BoBTFish Jul 03 '13 at 07:00
  • 4
    The problem is `::tolower`, not the iterators. You can't pass that function directly, because it takes two arguments. See here: http://stackoverflow.com/a/314163/777186 – jogojapan Jul 03 '13 at 07:01
  • @BoBTFish I'm just reading the error message... But I read the cplusplus doc and I apologize for non-thinking answer :) – Thomas Ayoub Jul 03 '13 at 07:03
  • @jogojapan That's what I was thinking, but I couldn't find a `tolower` taking a `locale&` anywhere on http://en.cppreference.com/mwiki/index.php?title=Special%3ASearch&search=tolower&button= – BoBTFish Jul 03 '13 at 07:04
  • I think there's a part of answer here : http://stackoverflow.com/questions/313970/stl-string-to-lower-case – Thomas Ayoub Jul 03 '13 at 07:05
  • @BoBTFish Yes, I am a bit confused now myself. There seem to be various `std::tolower` and `::tolower`. I had actually remembered the post I linked to and the rather complicated `bind2nd` expression used there. But when I try against GCC 4.8.1 now, the code given in the question here actually works with `::tolower` (but not `std::tolower`). – jogojapan Jul 03 '13 at 07:08
  • 2
    Ah ha, found it: http://en.cppreference.com/w/cpp/locale/tolower Has someone recently added `#include ` to your code? – BoBTFish Jul 03 '13 at 07:10
  • @BoBTFish I think you got the basis for an answer there.. – jogojapan Jul 03 '13 at 07:11
  • Nop, at locale was not added. – user2543099 Jul 03 '13 at 07:15
  • 1
    You should post a complete (but minimal) example, showing the includes you use, as well as any using directives and/or declarations. – juanchopanza Jul 03 '13 at 07:16
  • Its funny lol @ Samoth, I had to use that link and the unsuggested ans by no 198 which worked. But I would like to know why my code doesn't work. – user2543099 Jul 03 '13 at 07:17
  • 2
    `` et al are non-standard. Use ``, `` and ``. – Peter Wood Jul 03 '13 at 07:27

2 Answers2

2

If what you say, that this worked up until very recently, I must assume that someone has introduced a small change elsewhere in the code that breaks things. Now, this works:

#include <string>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <iostream>

int main()
{
    std::string s1 {"Hello"}, s2;
    std::transform(
            std::begin(s1),
            std::end(s1),
            std::back_inserter(s2),
            ::tolower);
    std::cout << s2 << '\n';
}

I.e. it prints hello. If I add these two lines at the top:

#include <locale>
using std::tolower;

I get a similar error to you (not identical). This is because it brings this version of tolower into scope. To get back the "proper" version (assuming you did mean the version in the cctype header?) you can use static_cast to pick the one you want:

// ...

#include <locale>
using std::tolower;

int main()
{
    std::string s1 {"Hello"}, s2;
    std::transform(
            std::begin(s1),
            std::end(s1),
            std::back_inserter(s2),
            static_cast<int(*)(int)>(::tolower)); // Cast picks the correct fn.
    std::cout << s2 << '\n';
}

Edit: I have to say, I'm confused as to why you are picking up that version specifically, rather than getting an ambiguous error. But I can't guess exactly what has been changed in your code...

BoBTFish
  • 19,167
  • 3
  • 49
  • 76
0

It works for me. Maybe you forgot to include <algorithm>.

It should work this way:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
   string ans;
    cin>>ans;
    std::transform(ans.begin(), ans.end(), ans.begin(), ::tolower);
   cout << ans;
   return 0;
}
petersohn
  • 11,292
  • 13
  • 61
  • 98
  • Indeed he should `#include ` but the error message suggests the compiler does know the signature of `transform`, so it is being picked up somehow or other (inside some other `include` I suppose). – BoBTFish Jul 03 '13 at 07:33
  • I tried it, and it worked for me that way. Maybe on your compiler you have to include something else for `tolower`? – petersohn Jul 05 '13 at 08:42