14

I've seen this a few times now, and I've been scratching my head wondering why...

As an example: (http://www.codeguru.com/forum/showthread.php?t=377394)

void LeftClick ( )
{  
  INPUT    Input={0};
  // left down 
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
  ::SendInput(1,&Input,sizeof(INPUT));

  // left up
  ::ZeroMemory(&Input,sizeof(INPUT));
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_LEFTUP;
  ::SendInput(1,&Input,sizeof(INPUT));
}

This example works without the :: (scope) operators so why are they even there?

replicant
  • 329
  • 3
  • 13
  • It also works if `// left down` is removed. So why is it there? For clarity. – tenfour Dec 30 '11 at 12:32
  • Assuming the OP is correct that it "works" even without the `::`, then yes, really. But I get that there's more to it, and this is why I didn't post as an answer. – tenfour Dec 30 '11 at 12:34
  • 4
    It's commonly used in Windows, where MFC classes often have member functions with the same name as global API functions. Using :: tells us that you really intended to call the API function. – Bo Persson Dec 30 '11 at 12:39
  • Is it? I never programmed much in Windows. Looks to me like yet another thing I could forget and screw something :-) – Giovanni Funchal Dec 30 '11 at 16:31
  • As I can't edit my previous comment to tenfour, my intention was saying that by adding useless `::`, your code gets more cluttered, not more clear. – Giovanni Funchal Dec 30 '11 at 16:33

6 Answers6

32

This basically mean "get the GLOBAL scoped function, instead of the currently visible one".

void SendInput() { /* (1) */
}

namespace derp {
    void SendInput() { /* (2) */
    }

    void LeftClick() {
        ...
        ::SendInput(); /* matches (1) */
        SendInput();  /* matches (2) */
    }
}
Giovanni Funchal
  • 8,934
  • 13
  • 61
  • 110
  • 3
    In this case (it means global). It actually mean use an "Absolute Namespace Path" not a "Relative Namespace Path". It just happens to be a short path in this context and thus in the global namespace. – Martin York Dec 30 '11 at 15:41
  • @LokiAstari Could you elaborate on the difference? Is it basically the same as referring to a file as `/path/to/file.txt` instead of `./path/to/file.txt` -- one is relative to the current position, the other is relative to a specific place? (in this case, the root folder) – Nic Feb 08 '16 at 08:58
  • @QPaysTaxes: A good analog. But you also need to apply the PATH variable to make the analog better. A relative path will be searched for in every directory in the path (while an absolute one will not). In the C++ case the PATH is represented by every nested scope from the current position. See https://gist.github.com/Loki-Astari/bddbdc98e8c8b9da5edc This makes realative paths susceptible to new code being added in a parent namespace. – Martin York Feb 08 '16 at 17:11
  • Does it have the same effect when used with classes ? `class Test : public ::OtherClass` – Winter Jul 14 '17 at 19:48
  • Yes @Winter (some characters) – Giovanni Funchal Jul 15 '17 at 20:13
3

Lets say you have the following:

void bar()
{
}

struct Foo
{
    void bar();
};

If you want to call the global function bar from the member function Foo::bar you use the syntax with empty left hand side:

void Foo::bar()
{
    // Call the global bar function, not recursively call myself
    ::bar();
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

It forces an absolute name resolution.
Without it name resolution is searched for relative to the class(s)/functions namespace path.

So assume LeftClick() is in the namespace hierarchy:

namespace Level1
{
    namespace Level2
    {
        namespace Level3
        {
            LeftClick()
            {
                 ::SendInput();   // Absolute path only. SendInput in global namespace
                 SendInput();     // Relative path (Note resolved at compile time)
                                  //
                                  // Looks for the function here (in this order)
                                  //    ::Level1::Level2::Level3::SendInput()
                                  //    ::Level1::Level2::SendInput()
                                  //    ::Level1::SendInput()
                                  //    ::SendInput()
            }
        }
    }
}

It becomes more interesting if you have a nested name:

namespace Level1
{
    namespace Level2
    {
        namespace Level3
        {
            LeftClick()
            {
                 ::Test::Action();  // Absolute Path: Function Action() 
                                    //                in namespace Test 
                                    //                in global namespace

                 Test::Action();    // Relative Path: Function Action()
                                    //                in namespace Test
                                    //                in current namespace path.
                                    //
                     // It will Look for Test (in this order)
                     // ::Level1::Level2::Level3::Test
                     // ::Level1::Level2::Test
                     // ::Level1::Test
                     // ::Test
                     //
                     // In the first Test (and only the first) it finds it will 
                     // try and resolve the Action() function. If it is not there
                     // it is a compile time error.
            }
        }
    }
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
1

It's to force the symbol to be looked up at global scope.

void foo() {} // 1

namespace A
{
    void foo() {} // 2

    void bar()
    {
        foo(); // 2
        ::foo(); // 1
    }
}
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
0

Using the scope operator in this fashion means that you are referring to the global scope.

To save me valuable time and keystrokes, check out scope resolution operator without a scope.

Community
  • 1
  • 1
Chris Parton
  • 1,052
  • 9
  • 16
0

The :: is used to give access to an object directly from outside of the object.

Software_Designer
  • 8,490
  • 3
  • 24
  • 28