#include <iostream>
// prints something;
// the template doesn't add anything
template <typename T>
struct Printer
{
void print()
{
std::cout << "Printer::print" << std::endl;
}
};
// this is an actual template
// calls the method indicated by the second template argument
// belonging to the class indicated by the first template argument
template < typename U, void(U::*func)()>
struct Caller
{
void call(U obj)
{
(obj.*func)();
}
};
// just a wrapper
template<typename V>
struct Wrapper
{
void call_caller_on_printer()
{
Printer<int> a_printer;
Caller<Printer<int>, &Printer<int>::print> caller;
caller.call(a_printer);
}
};
int main()
{
Wrapper<int> the_wrapper;
the_wrapper.call_caller_on_printer();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKLy8gcHJpbnRzIHNvbWV0aGluZzsgCi8vIHRoZSB0ZW1wbGF0ZSBkb2Vzbid0IGFkZCBhbnl0aGluZwp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IFByaW50ZXIKewogICAgdm9pZCBwcmludCgpCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJQcmludGVyOjpwcmludCIgPDwgc3RkOjplbmRsOwogICAgfQp9OwoKLy8gdGhpcyBpcyBhbiBhY3R1YWwgdGVtcGxhdGUKLy8gY2FsbHMgdGhlIG1ldGhvZCBpbmRpY2F0ZWQgYnkgdGhlIHNlY29uZCB0ZW1wbGF0ZSBhcmd1bWVudAovLyBiZWxvbmdpbmcgdG8gdGhlIGNsYXNzIGluZGljYXRlZCBieSB0aGUgZmlyc3QgdGVtcGxhdGUgYXJndW1lbnQKdGVtcGxhdGUgPCB0eXBlbmFtZSBVLCB2b2lkKFU6OipmdW5jKSgpPgpzdHJ1Y3QgQ2FsbGVyCnsKICAgIHZvaWQgY2FsbChVIG9iaikKICAgIHsKICAgICAgICAob2JqLipmdW5jKSgpOwogICAgfQp9OwoKLy8ganVzdCBhIHdyYXBwZXIKdGVtcGxhdGU8dHlwZW5hbWUgVj4Kc3RydWN0IFdyYXBwZXIKewogICAgdm9pZCBjYWxsX2NhbGxlcl9vbl9wcmludGVyKCkKICAgIHsKICAgICAgICBQcmludGVyPGludD4gYV9wcmludGVyOwogICAgICAgIENhbGxlcjxQcmludGVyPGludD4sICZQcmludGVyPGludD46OnByaW50PiBjYWxsZXI7CiAgICAgICAgY2FsbGVyLmNhbGwoYV9wcmludGVyKTsKICAgIH0KfTsKCmludCBtYWluKCkKewogICAgV3JhcHBlcjxpbnQ+IHRoZV93cmFwcGVyOwogICAgdGhlX3dyYXBwZXIuY2FsbF9jYWxsZXJfb25fcHJpbnRlcigpOwoKICAgIHJldHVybiAwOwp9