11

Why is this?

transform(theWord.begin(), theWord.end(), theWord.begin(), std::tolower); - does not work transform(theWord.begin(), theWord.end(), theWord.begin(), tolower); - does not work

but

transform(theWord.begin(), theWord.end(), theWord.begin(), ::tolower); - does work

theWord is a string. I am using namespace std;

Why does it work with the prefix :: and not the with the std:: or with nothing?

thanks for your help.

agf
  • 171,228
  • 44
  • 289
  • 238
user839913
  • 141
  • 1
  • 5

1 Answers1

21

using namespace std; instructs the compiler to search for undecorated names (ie, ones without ::s) in std as well as the root namespace. Now, the tolower you're looking at is part of the C library, and thus in the root namespace, which is always on the search path, but can also be explicitly referenced with ::tolower.

There's also a std::tolower however, which takes two parameters. When you have using namespace std; and attempt to use tolower, the compiler doesn't know which one you mean, and so it' becomes an error.

As such, you need to use ::tolower to specify you want the one in the root namespace.

This, incidentally, is an example why using namespace std; can be a bad idea. There's enough random stuff in std (and C++0x adds more!) that it's quite likely that name collisions can occur. I would recommend you not use using namespace std;, and rather explicitly use, e.g. using std::transform; specifically.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • So ::tolower tells the compiler look in the root name space, and std::tolower tells the compiler to look int the standard name space. Is that correct? And in this case I want the tolower from the root name space not the standard name space. – user839913 Jul 12 '11 at 02:28
  • Right. Or you could stop using `using namespace std` and tolower would work properly :) – bdonlan Jul 12 '11 at 03:00
  • 5
    Technically, OP's ::tolower() only exists due to an implementation detail. To guarantee that C library's `tolower` is in the global namespace, `` must be included rather than `` (see `D.5[depr.c.headers]/2`) – Cubbi Jul 12 '11 at 03:16
  • so if one includes and at the same time, std::tolower will be from which one? – Hayri Uğur Koltuk Feb 22 '13 at 12:36
  • @HayriUğurKoltuk Depends. Their definitions differ, so you'll have both. – tambre Jun 17 '18 at 11:31
  • The behavior of using `::tolower` is still unspecified, not only because `tolower` may not be in the global namespace as pointed out by Cubbi, but also because [one is usually not allowed to take the address of a standard library function](https://stackoverflow.com/a/55687045/5376789). – xskxzr Feb 18 '20 at 08:25