What Is the Meaning of Prepended Double Colon "::"

What is the meaning of prepended double colon ::?

This ensures that resolution occurs from the global namespace, instead of starting at the namespace you're currently in. For instance, if you had two different classes called Configuration as such:

class Configuration; // class 1, in global namespace
namespace MyApp
{
class Configuration; // class 2, different from class 1
function blah()
{
// resolves to MyApp::Configuration, class 2
Configuration::doStuff(...)
// resolves to top-level Configuration, class 1
::Configuration::doStuff(...)
}
}

Basically, it allows you to traverse up to the global namespace since your name might get clobbered by a new definition inside another namespace, in this case MyApp.

double colon after class name (declaration) - what does that mean?

Or is that an inner class declared out-of-the-main-class?

Bingo. To be super clear, iit's actually an inner class defined outside the enclosing class.

It's a handy trick if you want a class with member-like access to your class as an implementation detail, but do not want to publish that nested class's definition to the clients of your class.

what does a ampersand before double colon mean in c++?

It's two totally unrelated things, perhaps better thought of as

&(::google::protobuf::internal::kEmptyString)

& just means the address-of operator, exactly the same as if you'd done:

int xyzzy = 7;
int *pointer_to_xyzzy = &xyzzy;

The ::, on the other hand, is the global namespace specifier, to ensure you don't start looking in your current namespace.

For example, the following program:

#include <iostream>

int x = 7;
namespace xyzzy {
int x = 42;
int getxa() { return ::x; }
int getxb() { return x; }
}

int main() {
std::cout << xyzzy::getxa() << '\n';
std::cout << xyzzy::getxb() << '\n';
return 0;
}

outputs 7 followed by 42 since the getxa() function uses the global namespace specifier rather than the xyzzy one.

double colon for instance variables in c++

The :: is the scope-resolution operator and can be use to specify which of a number of symbols of the same name but different but visible scope the reference refers to.

Either scope-resolution or this-> may be used in this example, but scope-resolution itself has more general applicability within the language.

What does :: (double colon) stand for?

You can google for haskell "double colon" or similar things; it's unfortunately a bit hard to google for syntax, but in this case you can name it.

In Haskell, your programs will often run fine without it (though you will want to use it to hone the specification of any functions you define, and it is good practice).

The idea is that you can insert a :: ... anywhere (even in the middle of an expression) to say "by the way Mr. Compiler, this expression should be of type ...". The compiler will then throw an error if it can be proved this may not be the case.

I think you can also use it to "cast" functions to the versions you want; e.g. if a function is "polymorphic" (has a general type signature) and you actually want, say an Integer, then you could do :: Integer on the resulting value perhaps; I'm a bit rusty though.

What does double colon mean in this line?

https://doc.rust-lang.org/reference/paths.html#path-qualifiers

Paths can be denoted with various leading qualifiers to change the meaning of how it is resolved.

::

Paths starting with :: are considered to be global paths where the segments of the path start being resolved from the crate root. Each identifier in the path must resolve to an item.

So your idea was correct, it is resolving from the crate root.

I can't find where its defined in the crate root.

well libc doesn't in-and-of-itself define anything at the crate root, instead the crate root re-exports the content of the submodule matching the compilation target.

So on unix the "crate root" contains anything exposed by the fixed_width_ints and unix submodules. The former is not really useful for you, but the latter... does define a c_uint symbol.

Double Colon confusions

Why can I use double colons in functions and classes not defined but I can't use in variables ??

age is an instance field, it exists in multiple places in memory - one for each Person that exists.

I'll now expand in detail about what the :: operator does, how to use it, and how static class members compare to instance members:

The :: operator:

The :: (the scope-resolution operator) has multiple uses in C++:

If you're familiar with Java, C# or JavaScript then it can be likened to the dot dereference or "navigation operator" . (e.g. namespace.Class.Method().Result) - except C++ uses a different operators for different kinds of navigation and dereferencing:

  • . is the member-access operator, similar to C - it's only applicable for "object values" and references (foo&), not pointers (foo*).
  • -> is another member-access operator for pointer types, note that this operator can be overridden but . cannot (overridin -> is risky but it improves the ergonomics of smart-pointer libraries when done correctly).
  • :: is the scope-resolution operator - it has a few different uses:

    • Namespace navigation - whereas Java and C# use . to navigate packages and namespaces, C++ uses ::, for example: using std::time.
    • When unqualified, it's also used to reference the global namespace, e.g. ::std which is handy if you're writing code which is already in a namespace.
    • It's also used to access static members of types - typically an actual static member (a static method or field) but also items like enum class (scoped enumeration) values (e.g. SomeEnumClass::value_name)
    • Finally, it's also used to select a specific base method when dealing with virtual method implementations: it's used when an overridden method needs to call a base implementation in a superclass - C++ does not have the singular base or super keywords that C# and Java have (respectively) because C++ allows multiple inheritance, so you must specify the specific parent class name: How to call a parent class function from derived class function?

Anyway, in your case, it looks like you're confused about what instance and static members actually mean, so here is an illustration:

class Person {
public:
int height; // each Person has their own height, so this is an instance member
static int averageHeight; // but an individual Person doesn't have an "average height" - but a single average-height value can be used for all Persons, so this is a shared ("static") value.

int getAverageHeight() { // this is an instance method, btw
return Person::averageHeight; // use `Person::` to unambiguously reference a static member of `Person`
}

Person()
: height(0) {
// instance members should be initialized in the constructor!
}
}

// This will create an array of 10 people (10 different object instances).
// Each Person object (an instance) will have its own `height` in memory
Person* multiplePeople = new Person[10];

// btw, you probably should use `std::array` with an initializer instead:
// array<Person,10> multiplePeople{}; // <-- like this

// This sets a value to the `staticField` member, which exists only once in memory, that is, all Person instances share the same value for this member...
Person::averageHeight = 175; // 175cm

// ...for example:
assert( 175 == multiplePeople[3]->getAverageHeight() );
assert( 175 == multiplePeople[6]->getAverageHeight() );

// However instance members can have different values for each instance:
multiplePeople[3]->height = 170;
multiplePeople[6]->height = 180;

// Btw `height` is initialized to 0 in each Person's constructor.
assert( 170 != multiplePeople[0]->height );
assert( 180 != multiplePeople[7]->height );

What does prepending :: to a function call do in C++?

It means that the functions putenv() and tzset() will be looked up by the compiler in the global namespace.

Example

#include <iostream>

using namespace std;

//global function
void foo()
{
cout << "This function will be called by bar()";
}

namespace lorem
{
void foo()
{
cout << "This function will not be called by bar()";
}

void bar()
{
::foo();
}
}

int main()
{
lorem::bar(); //will print "This function will be called by bar()"
return 0;
}

double-colon (::) before method declaration in class definition

In general, it is not illegal to use the :: scope operator against the existing class scope to refer to its own members (even though it is redundant).

After the point of declaration of a class member, the member name can be looked up in the scope of its
class. [ Note: this is true even if the class is an incomplete class. For example,
struct X {

enum E { z = 16 };

int b[X::z];         // OK

};

C++11 §3.3.2 ¶5

The problem is that the definition of point of declaration seems to preclude using the scope operator in the member declaration if it is on its own name.

The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:

int x = 12;

{ int x = x; }

Here the second x is initialized with its own (indeterminate) value. — end example ]

C++11 §3.3.2 ¶1

There are no exceptions for class members in the paragraphs that follow in the rest of §3.3.2.

Even with the above restriction, the syntax for class members do not prohibit the use of a qualified-id for the member name. It is therefore not a syntax error to accept the shown code. But, there is a semantic violation, and a diagnostic should have been emitted.

C++'s double colon used after a class name instead of a namespace

You use the scope resolution operator (::) to name something in a namespace, or in a class, or in a scoped enum; this is called qualified lookup.

#include <iostream>

namespace N
{
int x = 0;
}

int main()
{
std::cout << N::x << '\n';
}

Using it with a class usually means you're referring to some static member, because otherwise you'd generally be using objectInstance.member instead.

#include <iostream>

class C
{
public:
static int x;
}

int C::x = 0;

int main()
{
std::cout << C::x << '\n';
}

Though, within a non-static member function, there are still uses for ::, such as disambiguating between names that exist concurrently in different bases.

class Base
{
public:
void foo() {}
};

class Derived : public Base
{
public:
void foo()
{
// Do base version (omitting Base:: will just call this one again!)
Base::foo();

// Now maybe do other things too
}
};

int main()
{
Derived obj;
obj.foo();
}

… or for naming a non-static member in a scenario where an object context is not required:

#include <iostream>

class C
{
public:
int x;
}

int main()
{
std::cout << sizeof(C::x) << '\n';

decltype(C::x) y = 42;
}

It's needed with scoped enums because, well, they're scoped; that's the whole point of them. They don't leak into the surrounding scope but have their own which as a result you need to specify specifically.

enum class E
{
Alpha,
Bravo,
Charlie
};

void foo(E value) {}

int main()
{
foo(E::Alpha);
}

Some languages let you access static members of classes with the type name followed by ., just like you'd access non-static members of classes with the object name followed by .. C++ is not one of those languages.

By the way, this is legal:

#include <iostream>

class C
{
public:
int x = 42;
};

int main()
{
C obj;
std::cout << obj.C::x << '\n';
// ^^^ what?!
}

Adding scope resolution to x here is not necessary, because the language already knows from the obj. that you're asking for a member of a class C. But you can still add it if you want. It's just usually "done for you" in this case.



Related Topics



Leave a reply



Submit