Difference between func() and (*this).func() in C++
I am working on someone else code in C++, and I found a weird call to a certain function func()
. Here is an example:
if(condition)
func();
else
(*this).func();
What is the difference between func()
and (*this).func()
?
What are the cases where the call to func()
and (*this).func()
will execute different code?
In my case, func()
is not a macro. It is a virtual function in the base class, with an implementation in both base and derived class, and no free func()
. The if
is located in a method in the base class.
There actually is a difference, but in a very non-trivial context. Consider this code:
void func ( )
{
std::cout << "Free function" << std::endl;
}
template <typename Derived>
struct test : Derived
{
void f ( )
{
func(); // 1
this->func(); // 2
}
};
struct derived
{
void func ( )
{
std::cout << "Method" << std::endl;
}
};
test<derived> t;
Now, if we call t.f()
, the first line of test::f
will invoke the free function func
, while the second line will call derived::func
.
It is impossible to tell from the snippet but possibly there are two callable objects called func()
. The (*this).func();
makes sure the member function is called.
A callable object could be (for example) a functor
or a lambda
expression:
functor
struct func_type
{
void operator()() const { /* do stuff */ }
};
func_type func; // called using func();
lambda
auto func = [](){ /* do stuff */ }; // called using func();
For example:
#include <iostream>
class A
{
public:
// member
void func() { std::cout << "member function" << '\n'; }
void other()
{
// lambda
auto func = [](){ std::cout << "lambda function" << '\n'; };
func(); // calls lambda
(*this).func(); // calls member
}
};
int main()
{
A a;
a.other();
}
Output:
lambda function
member function
Another case when those two lines will call different functions:
#include <iostream>
namespace B
{ void foo() { std::cout << "namespace\n"; } }
struct A {
void foo() { std::cout << "member\n"; }
void bar()
{
using B::foo;
foo();
(*this).foo();
}
};
int main ()
{
A a;
a.bar();
}