I found this line of a code in a class which I have to modify:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
and I don't know what exactly means the double colon prepended to the class name. Without that I would read: declaration of tmpCo
as a pointer to an object of the class Configuration
... but the prepended double colon confuses me.
I also found:
typedef ::config::set ConfigSet;
Lots of reasonable answers already. I'll chip in with an analogy that may help some readers.
::
works a lot like the filesystem directory separator '/
', when searching your path for a program you'd like to run. Consider:This is very explicit - only an executable at that exact location in the filesystem tree can match this specification, irrespective of the PATH in effect. Similarly...
...is equally explicit in the C++ namespace "tree".
Contrasting with such absolute paths, you can configure good UNIX shells (e.g. zsh) to resolve relative paths under any element in your
PATH
environment variable, so ifPATH=/usr/bin:/usr/local/bin
, then......would happily run
/usr/bin/X11/xterm
if found, else/usr/local/bin/X11/xterm
. Similarly, say you were in a namespace calledX
, and had a "using namespace Y
" in effect, then......could be found in any of
::X::std::cout
,::std::cout
,::Y::std::cout
, and possibly other places due to argument-dependent lookup (ADL, aka Koenig lookup). So, only::std::cout
is really explicit about exactly which object you mean, but luckily nobody in their right mind would ever create their own class/struct or namespace called "std
", nor anything called "cout
", so in practice using onlystd::cout
is fine.(A noteworthy difference is that shells tend to use the first match using the ordering in
PATH
, whereas C++ gives a compiler error when you've been ambiguous.)General discussion on namespaces and explicitness of symbols
Using absolute
::abc::def::...
"paths" can sometimes be useful to isolate you from any other namespaces you're using, part of but don't really have control over the content of, or even other libraries that your library's client code also uses. On the other hand, it also couples you more tightly to the existing "absolute" location of the symbol, and you miss the advantages of implicit matching in namespaces: less coupling, easier mobility of code between namespaces, and more concise, readable source code.As with many things, it's a balancing act. The C++ Standard puts lots of identifiers under
std::
that are less "unique" thancout
, that programmers might use for something completely different in their code (e.g.merge
,includes
,fill
,generate
,exchange
,queue
,toupper
,max
). Two unrelated non-Standard libraries have a far higher chance of using the same identifiers as the authors are generally un- or less-aware of each other. And libraries - including the C++ Standard library - change their symbols over time. All this potentially creates ambiguity when recompiling old code, particularly when there's been heavy use ofusing namespace
s: the worst thing you can do in this space is allowusing namespace
s in headers to escape the headers' scopes, such that an arbitrarily large amount of direct and indirect client code is unable to make their own decisions about which namespaces to use and how to manage ambiguities.So, a leading
::
is one tool in the C++ programmer's toolbox to actively disambiguate a known clash, and/or eliminate the possibility of future ambiguity....::
is a operator of defining the namespace.For example, if you want to use cout without mentioning
using namespace std;
in your code you write this:When no namespace is mentioned, that it is said that class belongs to global namespace.
::
is the scope resolution operator. It's used to specify the scope of something.For example,
::
alone is the global scope, outside all other namespaces.some::thing
can be interpreted in any of the following ways:some
is a namespace (in the global scope, or an outer scope than the current one) andthing
is a type, a function, an object or a nested namespace;some
is a class available in the current scope andthing
is a member object, function or type of thesome
class;some
can be a base type of the current type (or the current type itself) andthing
is then one member of this class, a type, function or object.You can also have nested scope, as in
some::thing::bad
. Here each name could be a type, an object or a namespace. In addition, the last one,bad
, could also be a function. The others could not, since functions can't expose anything within their internal scope.So, back to your example,
::thing
can be only something in the global scope: a type, a function, an object or a namespace.The way you use it suggests (used in a pointer declaration) that it's a type in the global scope.
I hope this answer is complete and correct enough to help you understand scope resolution.
(This answer is mostly for googlers, because OP has solved his problem already.) The meaning of prepended
::
- scope resulution operator - has been described in other answers, but I'd like to add why people are using it.The meaning is "take name from global namespace, not anything else". But why would this need to be spelled explicitly?
Use case - namespace clash
When you have the same name in global namespace and in local/nested namespace, the local one will be used. So if you want the global one, prepend it with
::
. This case was described in @Wyatt Anderson's answer, plese see his example.Use case - emphasise non-member function
When you are writing a member function (a method), calls to other member function and calls to non-member (free) functions look alike:
But it might happen that
Twist
is a sister member function of classA
, andBend
is a free function. That is,Twist
can use and modifym_couner
andBend
cannot. So if you want to ensure thatm_counter
remains 0, you have to checkTwist
, but you don't need to checkBend
.So to make this stand out more clearly, one can either write
this->Twist
to show the reader thatTwist
is a member function or write::Bend
to show thatBend
is free. Or both. This is very useful when you are doing or planning a refactoring.The
::
operator is called the scope-resolution operator and does just that, it resolves scope. So, by prefixing a type-name with this, it tells your compiler to look in the global namespace for the type.Example:
its called scope resolution operator, A hidden global name can be referred to using the scope resolution operator ::
For example;