Why is :: (scope) used with empty left-hand operand? [duplicate]

我与影子孤独终老i 提交于 2019-12-18 04:04:10

问题


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?


回答1:


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) */
    }
}



回答2:


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();
}



回答3:


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.
            }
        }
    }
}



回答4:


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
    }
}



回答5:


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.




回答6:


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



来源:https://stackoverflow.com/questions/8679457/why-is-scope-used-with-empty-left-hand-operand

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!