Why is colon used for this function?

I was looking at code for converting string into lower case. I bumped into this piece of code online where transform function is used
1
2
std::string s("hello");
std::transform(s.begin(), s.end(), s.begin(), ::tolower);

I am not able to understand why we need double colon for the function. Passing the function alone does not work. Are these object functors? Any explanation is greatly appreciated :)
Double colon is the scope resolution operator.
http://www.cplusplus.com/doc/tutorial/namespaces/

That piece of code did not specify using namespace std;
So you have to explicitly specify that string and transform are in the std namespace.
It's because std::transform needs to know where to find the tolower() function which is in the global namespace. Prepending a scope resolution operator(::) with no namespace given just means to look in the global namespace.
std::tolower is overloaded, there would (could) be an ambiguity if we use it.
http://en.cppreference.com/w/cpp/string/byte/tolower
http://en.cppreference.com/w/cpp/locale/tolower

An unqualified tolower would also be ambiguous if there is a using namespace std or using std::tolower in effect.

The qualified ::tolower is the tolower from the C standard library in the global namespace. (#include <ctype.h>)
Last edited on
Thanks guys,
@JLBorges: Which is the right way to do it, adding (#include <ctype.h>) and then calling ::toLower or calling std::lower directly?
I do not favour using deprecated features in any code that is freshly written.
Use of <ctype.h> (or any of the other C headers) is deprecated in C++.

This is what I strongly favour: #include <cctype> and then use a range-based loop
1
2
std::string str = "HELLO!" ;
for( char& c : str ) c = std::tolower(c) ;


If for some reason (homework?) std::transform must be used, a lambda expression comes in handy:
std::transform( str.begin(), str.end(), str.begin(), []( char c ) { return std::tolower(c) ; } ) ;

Legacy C++:
1
2
int (*tolower)(int) = &std::tolower ; // disambiguate
std::transform( str.begin(), str.end(), str.begin(), tolower ) ;
Oh Wow, awesome explanation. Thanks @JLBorges
Topic archived. No new replies allowed.