What does the scope resolution operator return in the case of Type :: var?

Consider the following example:

class A { int x; };

      

Now what is it A::x

?

  • It cannot be an lvalue because it does not refer to the storage location.
  • It cannot be a type, because the type will be decltype(A::x)

    .
+3


source to share


5 answers


It is, in fact, an lvalue. [expr.prim.id.qual] / 2 :

A nested qualifier name denoting a class [...] followed by the name of a member of that class ([class.mem]) or one of its base classes is a qualified identifier [...]. The result is a member. Result type - element type. The result is an lvalue if the member is a static member function or data member, and a prvalue otherwise.



Although its use outside of a class member access expression is severely restricted [expr.prim.id] / 2 , it can be used, in particular, in non-evaluated operands, where its lvalueness may appear:

struct A {
    int x;
};

void f(int &);

using p = decltype(&(A::x)); // p is int*; the parens prevents forming a pointer-to-member
using q = decltype(f(A::x)); // q is void

      

+11


source


A::x

is just a less ambiguous way of referring to a member x

, which may be needed if the local context shadows that member:


Example 1:

The child class also has a member x

.

struct B : public A
{
    int x;
    void foo()
    {
        int local_x = x;
        int parent_x = A::x;
    }
}

      



which will compile if you did x

protected

in the class A

(currently private

).


Example 2:

You can even use it in a member function A

that has x

as a parameter:

class A {
    int x;
    void foo(int x)
    {
        int parameter_x = x;
        int member_x = A::x;
    }
};

      

+6


source


In addition to the answer from Bathsheba, which is correct when you are within a class A::x

can also be used as part of a pointer-member expression, i.e. &A::x

which returns int A::*

.

In this case, offline is A::x

invalid and therefore the question of what it returns is moot.

+2


source


From C ++ Standard (5.1 Primary Expressions)

9 A nested qualifier name designating a class, optionally followed by a keyword template (14.2), followed by the name of a member of either that class (9.2) or one of its base classes (clause 10), is a qualified identifier; 3.4.3.1 describes name lookups for class members that appear in qualified identifiers. The result is a member. The type of the result is the type of the member. The result is an lvalue if the member is a static member function or data member, and a prvalue otherwise. [Note: A class member can refer to the use of a qualified identifier at any point in its potential scope (3.3.7). -end note] ...

A qualified name allows you to specify an otherwise hidden name, for example, when derived and base classes have members with the same name. for example

#include <iostream>

struct A
{
    int i;
};

struct B : A
{
    B( int i ) : A { i }, i( 2 * A::i ) {}
    int i;
    std::ostream &out( std::ostream &os = std::cout ) const
    {
        return os << "A::i = " << A::i << ", B::i = " << B::i;
    }
};

int main() 
{
    B( 10 ).out() << std::endl;

    return 0;
}

      

Program output

A::i = 10, B::i = 20

      

See also (5.1 Primary Expressions)

13 An identifier that denotes a non-static data member or non-static function of a class member can only be used:

(13.1) - as part of a member access of a class (5.2.5) in which an object expression refers to members of a class63 or a class derived from that class, or

(13.2) - to form a pointer to an element (5.3.1) or

(13.3) - if this id-expression denotes a non-static data member and it appears in an unpublished operand.

0


source


A::x

is the exact equivalent of static variable access in JAVA.

Regarding your example: -

1) x will be variable for different objects

2) A :: x will be a variable for the class itself. No matter how many objects from A were declared for each object, the value A::x

will be the same prior to assignment.

For example: -

#include<iostream>

using namespace std;

class A { 
public:
   static int x; 
};

int A::x;

int main()
{
   A a,b;

   a.x=8;

   b.x=6;

   A::x=10;


   return 0;
}

      

-3


source







All Articles