'Using :: (scope resolution operator) in C++
I am learning C++ and I can never tell when I need to use ::
. I do know that I need to use std::
in front of cout
and cin
. Does this mean that inside of the iostream
file the developers that created it made a namespace called std
and put the functions cin
and cout
into the namespace called std
? When I created a new class that isn't in the same file as main()
for some reason I must add ::
.
For example, if I create a class
called A
, why do I need to put A::
in front of a function that I make, even though I didn't put it into a namespace? For example void A::printStuff(){}
. If I create a function in main
, why don't I have to put main::printStuff{}
?
I know that my question is probably confusing, but could someone help me?
Solution 1:[1]
You're pretty much right about cout
and cin
. They are objects (not functions) defined inside the std
namespace. Here are their declarations as defined by the C++ standard:
Header
<iostream>
synopsis#include <ios> #include <streambuf> #include <istream> #include <ostream> namespace std { extern istream cin; extern ostream cout; extern ostream cerr; extern ostream clog; extern wistream wcin; extern wostream wcout; extern wostream wcerr; extern wostream wclog; }
::
is known as the scope resolution operator. The names cout
and cin
are defined within std
, so we have to qualify their names with std::
.
Classes behave a little like namespaces in that the names declared inside the class belong to the class. For example:
class foo
{
public:
foo();
void bar();
};
The constructor named foo
is a member of the class named foo
. They have the same name because its the constructor. The function bar
is also a member of foo
.
Because they are members of foo
, when referring to them from outside the class, we have to qualify their names. After all, they belong to that class. So if you're going to define the constructor and bar
outside the class, you need to do it like so:
foo::foo()
{
// Implement the constructor
}
void foo::bar()
{
// Implement bar
}
This is because they are being defined outside the class. If you had not put the foo::
qualification on the names, you would be defining some new functions in the global scope, rather than as members of foo
. For example, this is entirely different bar
:
void bar()
{
// Implement different bar
}
It's allowed to have the same name as the function in the foo
class because it's in a different scope. This bar
is in the global scope, whereas the other bar
belonged to the foo
class.
Solution 2:[2]
The ::
are used to dereference scopes.
const int x = 5;
namespace foo {
const int x = 0;
}
int bar() {
int x = 1;
return x;
}
struct Meh {
static const int x = 2;
}
int main() {
std::cout << x; // => 5
{
int x = 4;
std::cout << x; // => 4
std::cout << ::x; // => 5, this one looks for x outside the current scope
}
std::cout << Meh::x; // => 2, use the definition of x inside the scope of Meh
std::cout << foo::x; // => 0, use the definition of x inside foo
std::cout << bar(); // => 1, use the definition of x inside bar (returned by bar)
}
unrelated: cout and cin are not functions, but instances of stream objects.
Solution 3:[3]
The ::
is called scope resolution operator.
Can be used like this:
::
identifier
class-name ::
identifier
namespace ::
identifier
You can read about it here
https://docs.microsoft.com/en-us/cpp/cpp/scope-resolution-operator?view=vs-2017
Solution 4:[4]
One use for the 'Unary Scope Resolution Operator' or 'Colon Colon Operator' is for local and global variable selection of identical names:
#include <iostream>
using namespace std;
int variable = 20;
int main()
{
float variable = 30;
cout << "This is local to the main function: " << variable << endl;
cout << "This is global to the main function: " << ::variable << endl;
return 0;
}
The resulting output would be:
This is local to the main function: 30
This is global to the main function: 20
Other uses could be: Defining a function from outside of a class, to access a static variable within a class or to use multiple inheritance.
Solution 5:[5]
look at it is informative [Qualified identifiers
A qualified id-expression is an unqualified id-expression prepended by a scope resolution operator ::, and optionally, a sequence of enumeration, (since C++11)class or namespace names or decltype expressions (since C++11) separated by scope resolution operators. For example, the expression std::string::npos is an expression that names the static member npos in the class string in namespace std. The expression ::tolower names the function tolower in the global namespace. The expression ::std::cout names the global variable cout in namespace std, which is a top-level namespace. The expression boost::signals2::connection names the type connection declared in namespace signals2, which is declared in namespace boost.
The keyword template may appear in qualified identifiers as necessary to disambiguate dependent template names]1
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | nbro |
Solution 3 | Vladislav |
Solution 4 | Community |
Solution 5 | vincent87 |