Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42909

Resolving explicitly the scope of a class member

Consider the following example:

#include <iostream>

struct foo {
    void fun() const { std::cout << "foo::fun()" << std::endl; }
};

auto main() -> int {
  foo f;
  f.fun();
  f.foo::fun();

  return 0;
}

DEMO

Questions:

  1. What's the difference between the two calls (i.e., f.fun() and f.foo::fun())?
  2. Are there any advantages in calling a member function or a publicly accessible member variable by explicitly disambiguating its scope against calling it in the classical way?
  3. Are there any pitfalls in calling a member function or a publicly accessible member variable by explicitly disambiguating its scope?

Upvotes: 3

Views: 126

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311018

In your example there is no any semantic difference of the calling syntax.

However consider the following example

#include <iostream>

struct A
{
   void f() { std::cout << "A::f()" << std::endl; }
};

struct B : A
{
   void f() { std::cout << "B::f()" << std::endl; }
};

int main()
{
   B b;

   b.f();
   b.A::f();
}

Or consider a more interesting example though it has no any greate sense but it is interesting from the point of view of the scope resolution.

#include <iostream>

struct A
{
    virtual ~A() { std::cout << "A::~A()" << std::endl; };
};

struct B : A
{
     ~B() { std::cout << "B::~B()" << std::endl; };
};


int main() 
{
    B b1;

    b1.~A();

    std::cout << "End of the first part\n\n";

    B b2;

    b2.A::~A();

    std::cout << "End of the second part\n\n" << std::endl;

    return 0;
}

The output will be

B::~B()
A::~A()
End of the first part

A::~A()
End of the second part


B::~B()
A::~A()
B::~B()
A::~A()

Take into account that I called purposely destructor with name ~A

Upvotes: 2

Praetorian
Praetorian

Reputation: 109159

One difference is that if fun() were a virtual function, calling it the second way would inhibit virtual dispatch.

struct foo {
    void virtual fun() const { std::cout << "foo::fun()" << std::endl; }
};
struct bar : foo {
    void fun() const override { std::cout << "bar::fun()" << std::endl; }
};

auto main() -> int {
  bar b;
  foo *f = &b;
  f->fun();
  f->foo::fun();
}

Outputs:

bar::fun()
foo::fun()

Live demo


Similarly if you were instead hiding a function from the base class, it allows you to access the base class version.

struct foo {
    void fun() const { std::cout << "foo::fun()" << std::endl; }
};
struct bar : foo {
    void fun(int) const { std::cout << "bar::fun()" << std::endl; }
};

auto main() -> int {
  bar b;
  b.fun(10);
  b.foo::fun();
}

Upvotes: 9

Related Questions