#include <iostream>
#include <type_traits>
struct Foo {};
struct Bar {};
struct Baz : Foo, Bar
{
public:
virtual void something(const Bar &bar)
{ std::cout << "Bar\n"; }
template <class T, class = typename std::enable_if<std::is_convertible<const T&, const Foo&>::value && !std::is_convertible<const T&, const Bar&>::value>::type>
void something (const T &foo)
{ something_impl(static_cast<const Foo&>(foo)); }
private:
virtual void something_impl(const Foo &foo)
{ std::cout << "Foo\n"; }
};
int main()
{
Baz baz;
baz.something(baz);
Foo foo;
baz.something(foo);
Bar bar;
baz.something(bar);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzdHJ1Y3QgRm9vIHt9OwoKc3RydWN0IEJhciB7fTsKCnN0cnVjdCBCYXogOiBGb28sIEJhcgp7CnB1YmxpYzoKICB2aXJ0dWFsIHZvaWQgc29tZXRoaW5nKGNvbnN0IEJhciAmYmFyKQogIHsgc3RkOjpjb3V0IDw8ICJCYXJcbiI7IH0KCiAgdGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzID0gdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8c3RkOjppc19jb252ZXJ0aWJsZTxjb25zdCBUJiwgY29uc3QgRm9vJj46OnZhbHVlICYmICFzdGQ6OmlzX2NvbnZlcnRpYmxlPGNvbnN0IFQmLCBjb25zdCBCYXImPjo6dmFsdWU+Ojp0eXBlPgogIHZvaWQgc29tZXRoaW5nIChjb25zdCBUICZmb28pCiAgeyBzb21ldGhpbmdfaW1wbChzdGF0aWNfY2FzdDxjb25zdCBGb28mPihmb28pKTsgfQoKcHJpdmF0ZToKICB2aXJ0dWFsIHZvaWQgc29tZXRoaW5nX2ltcGwoY29uc3QgRm9vICZmb28pCiAgeyBzdGQ6OmNvdXQgPDwgIkZvb1xuIjsgfQoKfTsKCmludCBtYWluKCkKewoJQmF6IGJhejsKCWJhei5zb21ldGhpbmcoYmF6KTsKCQoJRm9vIGZvbzsKCWJhei5zb21ldGhpbmcoZm9vKTsKCQoJQmFyIGJhcjsKCWJhei5zb21ldGhpbmcoYmFyKTsKfQ==