#include <iostream>
#include <typeinfo>

class B;

struct A {
	decltype(auto) func(B*);
	decltype(auto) func(B&);
};

template<typename T>
void size() {
	std::cout << "Size of " << typeid(T).name() << ": " << sizeof(T) << '\n';
}

template<>
void size<B*>() {
	std::cout << "Size of B*: " << sizeof(B*) << '\n';
}

// Error if uncommented.
//template<>
//void size<B>() {
//	std::cout << "Size of B: " << sizeof(B) << '\n';
//}

class B {
	friend class A;
	
	void func() const { std::cout << "Be funky.\n"; }
};

decltype(auto) A::func(B* b) { return b->func(); }
decltype(auto) A::func(B& b) { return b.func(); }

int main() {
	A a;
	B b;
	
	a.func(b);
	a.func(&b);
	
	size<B*>();
	size<B>();
}