#include <type_traits>
struct A { int x; };
struct B { int x; };
struct C { int x; };
struct D { int x; };
template <class ... Params> class Parameter { };
template <class Param>
class Parameter<Param> : public Param
{
public:
//! Get a parameter
template <class Param2>
typename std::enable_if<std::is_same<Param, Param2>::value, int>::type
getParam() const
{ return Param::x; }
};
template <class Param, class ... Tail>
class Parameter<Param, Tail ...> : public Param, public Parameter<Tail ...>
{
public:
using Parameter<Tail ...>::getParam;
//! Get a parameter
template <class Param2>
typename std::enable_if<std::is_same<Param, Param2>::value, int>::type
getParam() const
{ return Param::x; }
};
class Base : public Parameter<A, B>
{ };
class Derived : public Base, public Parameter<C, D>
{
public:
using Base::getParam;
using Parameter<C, D>::getParam;
};
int main(int const argc, char const * argv[])
{
Base base;
int a = base.getParam<A>(); // ok
int b = base.getParam<B>(); // ok
Derived derived;
int c0 = derived.getParam<C>();
int c1 = derived.Derived::getParam<C>();
int c2 = derived.Parameter<C, D>::getParam<C>();
int a0 = derived.getParam<A>();
int a1 = derived.Base::getParam<A>();
int a2 = derived.Parameter<A, B>::getParam<A>();
return 0;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKc3RydWN0IEEgeyBpbnQgeDsgfTsKc3RydWN0IEIgeyBpbnQgeDsgfTsKc3RydWN0IEMgeyBpbnQgeDsgfTsKc3RydWN0IEQgeyBpbnQgeDsgfTsKCnRlbXBsYXRlIDxjbGFzcyAuLi4gUGFyYW1zPiBjbGFzcyBQYXJhbWV0ZXIgeyB9OwoKdGVtcGxhdGUgPGNsYXNzIFBhcmFtPgpjbGFzcyBQYXJhbWV0ZXI8UGFyYW0+IDogcHVibGljIFBhcmFtCnsKcHVibGljOgogICAgLy8hIEdldCBhIHBhcmFtZXRlcgogICAgdGVtcGxhdGUgPGNsYXNzIFBhcmFtMj4KICAgIHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPHN0ZDo6aXNfc2FtZTxQYXJhbSwgUGFyYW0yPjo6dmFsdWUsIGludD46OnR5cGUKICAgIGdldFBhcmFtKCkgY29uc3QKICAgIHsgcmV0dXJuIFBhcmFtOjp4OyB9Cn07Cgp0ZW1wbGF0ZSA8Y2xhc3MgUGFyYW0sIGNsYXNzIC4uLiBUYWlsPgpjbGFzcyBQYXJhbWV0ZXI8UGFyYW0sIFRhaWwgLi4uPiA6IHB1YmxpYyBQYXJhbSwgcHVibGljIFBhcmFtZXRlcjxUYWlsIC4uLj4KewpwdWJsaWM6CiAgICB1c2luZyBQYXJhbWV0ZXI8VGFpbCAuLi4+OjpnZXRQYXJhbTsKICAgIC8vISBHZXQgYSBwYXJhbWV0ZXIKICAgIHRlbXBsYXRlIDxjbGFzcyBQYXJhbTI+CiAgICB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX3NhbWU8UGFyYW0sIFBhcmFtMj46OnZhbHVlLCBpbnQ+Ojp0eXBlCiAgICBnZXRQYXJhbSgpIGNvbnN0CiAgICB7IHJldHVybiBQYXJhbTo6eDsgfQp9OwoKY2xhc3MgQmFzZSA6IHB1YmxpYyBQYXJhbWV0ZXI8QSwgQj4KeyB9OwoKY2xhc3MgRGVyaXZlZCA6IHB1YmxpYyBCYXNlLCBwdWJsaWMgUGFyYW1ldGVyPEMsIEQ+CnsKcHVibGljOgogICAgdXNpbmcgQmFzZTo6Z2V0UGFyYW07CiAgICB1c2luZyBQYXJhbWV0ZXI8QywgRD46OmdldFBhcmFtOwp9OwoKaW50IG1haW4oaW50IGNvbnN0IGFyZ2MsIGNoYXIgY29uc3QgKiBhcmd2W10pCnsKICBCYXNlIGJhc2U7CiAgaW50IGEgPSBiYXNlLmdldFBhcmFtPEE+KCk7IC8vIG9rCiAgaW50IGIgPSBiYXNlLmdldFBhcmFtPEI+KCk7IC8vIG9rCgogIERlcml2ZWQgZGVyaXZlZDsKICBpbnQgYzAgPSBkZXJpdmVkLmdldFBhcmFtPEM+KCk7CiAgaW50IGMxID0gZGVyaXZlZC5EZXJpdmVkOjpnZXRQYXJhbTxDPigpOwogIGludCBjMiA9IGRlcml2ZWQuUGFyYW1ldGVyPEMsIEQ+OjpnZXRQYXJhbTxDPigpOwoKICBpbnQgYTAgPSBkZXJpdmVkLmdldFBhcmFtPEE+KCk7CiAgaW50IGExID0gZGVyaXZlZC5CYXNlOjpnZXRQYXJhbTxBPigpOwogIGludCBhMiA9IGRlcml2ZWQuUGFyYW1ldGVyPEEsIEI+OjpnZXRQYXJhbTxBPigpOwoKICByZXR1cm4gMDsKfQo=