what is this operator?

Hello

I downloaded a video from Microsoft MSDN and it was about "How Do I: Quickly Create Simple Applications using MFC?", in the video he use an operator that i didn't recognize. Here is the part where he used it:

DWORD dwDvices =:: GetLogicalDrives();

the operator is =::

So what's this operator?

And why when i remove :: the program runs normally?





You probably mean:
 
DWORD dwDvices = ::GetLogicalDrives();
Is that the case?
= and :: are separate operators - as far as I am aware there is no =:: operator.

I'm guessing you know what = does.

:: Is the scope resolution operator (have you heard of this one?)
So prefacing a symbol with :: makes the compiler look in the global scope for it. As the compiler checks in the global scope anyway for symbols, this is generally unnecessary (thus your program works without it).

However, there are some situations where it is necessary to resolve an ambiguous symbol reference.
thank Xander314

i got it now. great explanation.
but from which class / namespace / structure / whatever it refer from?
closed account (yUq2Nwbp)
chipp it isn't necessary for GetLogicalDrives() to be in class or namespace.....if you have two variables with the same name in main() and in global scope then if you want to use globale variable you must write for example

int x;
int main()
{
int x;
::x=8; //compiler will understand global x

}
but from which class / namespace / structure / whatever it refer from?

So just to make it clear ::GetLogicalDrives() refers to a function called GetLogicalDrives in the global namespace.
so, like:
1
2
3
4
5
using namespace std;

int main () {

::string my_string = "..."; //is valid? 
No; that's kind of the whole point of ::___.

1
2
3
4
5
6
7
8
9
10
11
12
#include <string>
class string;

using namespace std; //Whoops! Now the data type "string" is ambiguous.

int main() {
   ::string a; //our UDT string, found in the global namespace
   std::string b; //the standard library's string, found in namespace std
}

//define ::string
...
Last edited on
closed account (z05DSL3A)
Chipp,
your example is valid however there is no reason in that code to require it.

In the following code there is a reason to distinguish between different strings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
 
using namespace std; // dump everything from std:: into global namespace

int main()
{
    struct string
    {
        std::string aString; // use std::string from std namespace
    };

    string aString;          // using the above string struct

    ::string bString;        // use std::string via global namespace
                             // only valid because std namespace has be dumped
                             // into the global namespace

    std::string cString;     // use std::string from std namespace

    return 0;
}
Last edited on
Are you sure Grey Wolf? I was under the impression that the ::___ told to compiler to explicitly look in the global namespace, much the same way that __::___ told it to look in that namespace. Then using ___ or using namespace __ would allow the compiler to implicitly look for that data type where ever you asked it to, plus the global namespace.
Last edited on
closed account (z05DSL3A)
It is not quite as simplistic as the comments suggest.

Here is an explanation of using Declarations and using directive:
using Declarations, ie:
1
2
3
using std::cout;
using std::cin;
using std::endl


add names to the scope in which they are declared. The effect of this is:
» a compilation error occurs if the same name is declared elsewhere in the same scope;
» if the same name is declared in an enclosing scope, the the name in the namespace hides it.

The using directive, ie using namespace std;, does not add a name to the current scope, it only makes the names accesable from it. This means that:
» If a name is declared within a local scope it hides the name from the namespace;
» a name in a namespace hides the same name from an enclosing scope;
» a compilation error occurs if the same name is made visible from multiple namespaces or a name is made visible that hides a name in the global name space.

Global scope resolution (::Name) tells the compiler to look for the name at global scope rather than local or any other. If you have used a using directive in the global scope all the names are accessible via that scope.

full scope resolutions (namspace::name) tells the compiler exactly where to look.
your example is valid however there is no reason in that code to require it.

well, it just an for an example. btw, you mean "there's no reason to require it" is because there's only one "string" in that example, so we don't have to distinguish it with another "string" type (like in your code)?

btw, i tried your code, but like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <conio.h> 
using namespace std; // dump everything from std:: into global namespace

struct string {
        std::string aString; // use std::string from std namespace
};

int main()
{
    string aString;          // using the above string struct

    ::string bString;        // use std::string via global namespace
                             // only valid because std namespace has be dumped
                             // into the global namespace

    std::string cString;     // use std::string from std namespace
	getch();
    return 0;
}


instead your code, why this failed? is the struct has to be in main() ? why?

note: <string> doesn't required, it's been in std::string
Last edited on
closed account (yUq2Nwbp)
chipp as Grey wolf said

using namespace std does not add a name to the current scope, it only makes the names accesable from it.

...so your code failed because this expression i think meanless ::string bString;.....with this :: symbol you access global variable.. for example

int k;
int main()
{
::k=8;
}
from your writing it seem's that you wanted to use global type.....but it is meanless..


Last edited on
closed account (z05DSL3A)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
 
using namespace std; // dump everything from std:: into global namespace

struct string {
        std::string aString; // use std::string from std namespace
};

int main()
{
    string aString;          // Ambiguous string the compiler does not know
                             // which string you want out of the two that it
                             // see (std::string and ::string)

    ::string bString;        // The compiler is being told to use the ::string
                             // so it uses the struct string

    std::string cString;     // use std::string from std namespace
	
    return 0;
}
@grey: so if there's no global variable, then

::string

is equal to std::string (assuming std is being used ad global namespace) because it's the only global "thing" in the code, while the code above is not?

@david: i don't think so. i thought you should take a look at grey's
closed account (yUq2Nwbp)
chipp i agree with you and i already looked and agreed with grey...
Last edited on
closed account (z05DSL3A)
Chipp,

Yes (if I understand you).
-_-! come on dude. alright i'll explain what i mean on my previous question:

if:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

//notice there's only 1 global "thing" in here, which is the "std"
//and it's a namespace

using namespace std;

int main() {

    //so, if i wrote:
    ::string mystring;
    //the compiler would search the string member from the std namespace because it is the
    //only global variable. and ::string itself is definitely equal to std::string
}


different from:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;

struct string {
//...
};

int main() {

    ::string mystring;
    //this won't be equivalent to std::string because there's another string (the struct)
    //thus, the compiler is confused with it (is it the global variable or the string member of std)
}


am i right? (i just want to verify my comprehension, so there's no misunderstanding)
closed account (z05DSL3A)
Okay, you are almost there.

In the first pice of code; the scope resolution operator (::) tell the complier to ignore any local names that it might match string to and go directly to the global scope. Here it does not find any names in the global scope that match but due to the using directive it can see that there is a name in std:: that it can match to and so uses that.

In the second pice of code; again the compiler is told to go directly to the global scope and here it finds a matching name (struct string) so it uses that.

if you did not use scope resolution, the compiler would eventually get to the global scope. Here it has a name in that scope (struct string) but can also 'see' there is a std::string that it could match to. This is when it doesn't have enough info to decide which to use and gives an error.


Topic archived. No new replies allowed.