1

On S.O. posts such as How to convert std::string to lower case?, I've seen the syntax ::something, e.g.

std::transform(data.begin(), data.end(), data.begin(), ::tolower);

and I'm wondering what that means. I know that std::transform looks for a function or variable named transform inside the namespace std. But what does the scope operator mean when it doesn't have a first argument?

Community
  • 1
  • 1

3 Answers3

5
::tolower

means that tolower would be looked up in global namespace

ravi
  • 10,994
  • 1
  • 18
  • 36
4

But what does the scope operator mean when it doesn't have a first argument?

It denotes the global namespace.

Consider a simple example. Let;s assume that you defined function swap. At the same time you included header <utility> that also contains a declaration of swap. and after it dirrective using namespace std; To distinguihs them you need to use qualified name.

#include <iostream>
#include <utility>

using namespace std;


void swap( int &x, int &y )
{
    std::cout << "Inside ::swap" << std::endl;
    int tmp = x;
    x = y + 10;
    y = tmp + 10;
}

int main() 
{
    int x = 1;
    int y = 2;

    std::swap( x, y );

    std::cout << "x = " << x << ", y = " << y << std::endl;

    x = 1;
    y = 2;

    ::swap( x, y );

    std::cout << "x = " << x << ", y = " << y << std::endl;


    return 0;
}

The output will be

x = 2, y = 1
Inside ::swap
x = 12, y = 11

In this example ::swap refers to your function swap defined in the global namespace while std::swap refers to standard function swap declared in name space std in header <utility>

If you will write unqualified name

swap( x, y );

when the compiler will not know which function to call: either standard function std::swap or your own function ::swap

If to exclude directive

using namepsace std;

and write

swap( x, y );

then the compiler will call your own function swap.

Now I will explain why in your example with standard algorithm std::transform there is used ::tolower. The problem is that in C++ there are two functions with name tolower. One of which is C standard function declared in header <cctype> and other is C++ function declared in header <locale>. The C++ Standard allows to place C standard functions in the global namespace. So using name ::tolower allows the compiler to select the C standard function instead of the C++ function.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

The std::transform function iterates over a sequence and applies a transformation function for each element.

The last argument is a so called functor, which may be a function pointer or an object of a class implementing operator(). Functor is a concept very widely applied in algorithm-part of std lib.

e.g.: very useful function converting all characters to a given character:

int testAnywhereInCppCode()
{
    struct ToAnotherChar
    {   
        char _toChar;
        ToAnotherChar( char toChar):_toChar(toChar){}
        char operator()(char c){ return _toChar; }
    };

    ToAnotherChar toAnotherCharConverter('x');

    std::string data = "Hello World";

    std::transform(data.begin(), data.end(), data.begin(), toAnotherCharConverter);
    return 0;
}

static int testAnywhereInCppCodeCaller = testAnywhereInCppCode();

:: means only the global namespace, where std::toLower is implemented.

However std::toLower is only a standard way to make lower-case. You could implement your own (e.g. for a very exotic charset) and use it with std::transform

Valentin H
  • 7,240
  • 12
  • 61
  • 111