#include <iostream>
struct A
{
int mf( int a ) { return m += a ; }
int m = 0 ;
};
int fn( int a ) { return a*2 ; }
int main()
{
A a ;
// a. pointer to object (T* where T is an object type)
auto pa = std::addressof(a) ; // pointer to A
auto& ra = *pa ; // dereference (unary * operator): type of *pa is A, value category is lvalue
bool b = pa ; // implicit conversion to bool
void* pv = pa ; // implicit conversion to 'pointer to void'
// *pv ; // *** error: pv is not a 'pointer to object'
std::cout << pv << '\n' ; // ostream::operator<< ( const void* )
std::cout << pa << '\n' ; // implicit conversion from 'pointer to A' to 'pointer to const void'
//-------------------------------------------
// b. pointer to function (F* where F is a non-member or static member function)
using fn_type = int(int) ;
fn_type* pfn = &fn ; // pointer to function
pfn = fn ; // implicit conversion: 'function' to 'pointer to function'
b = pfn ; // implicit conversion: 'pointer to function' to bool
// pv = pfn ; // *** error: type of pfn is not a pointer to object type
auto& rfn = *pfn ; // dereference (unary * operator): type of rfn is 'reference to function'
std::cout << b << '\n' ; // ostream::operator<< ( bool )
std::cout << pfn << '\n' ; // implicit conversion from 'pointer to function' to 'bool' (true)
pfn = nullptr ;
std::cout << pfn << '\n' ; // implicit conversion from 'pointer to function' to 'bool' (false)
//-------------------------------------------
// c. pointer to member T::*m (where T is a class type)
auto pmo = &A::m ; // pointer to member object
auto pmf = &A::mf ; // pointer to member function
// *pmf ; // *** error: type of pmf is not a pointer to object type
// pv = pmf ; // *** error: type of pmf is not a pointer to object type
b = pmf ; // implicit conversion to bool
std::cout << b << '\n' ; // ostream::operator<< ( bool )
std::cout << pmf << '\n' ; // implicit conversion from 'pointer to member function' to 'bool'
// pointer to member operators .* ->*
a.*pmo = 7 ;
(pa->*pmf)(23) ;
}