#include<iostream>
class HasFoo
{
public :
typedef char (&Small)[1];
typedef char (&Large)[2];
template <typename C, void (C::*) ()> class SFINAE {};
template <typename C> static Small test (SFINAE<C, &C::foo> *)
{
std::cout << "HAS" << std::endl;
}
template <typename C> static Large test (...)
{
std::cout << "NOT HAS" << std::endl;
}
};
class B
{
public :
void foo () {}
};
class D1 : public B
{
private: void foo () {} // override
};
class D2 : public B
{
public :
using B::foo;
};
class D3 : public B {};
/////////////////////////////////////////////////////////////////
template<typename C, void (C::*p)()>
struct X{};
template struct X<D1,&D1::foo>; //<--- private members can be used in explicit instantiation
//////////////////////////////////////////////////////////////////
int main ()
{
// HasFoo::test<B>(0);
// HasFoo::test<D1>(0);
// HasFoo::test<D2>(0);
// HasFoo::test<D3>(0);
}
I2luY2x1ZGU8aW9zdHJlYW0+CmNsYXNzIEhhc0Zvbwp7CiAgICBwdWJsaWMgOgoKICAgIHR5cGVkZWYgY2hhciAoJlNtYWxsKVsxXTsKICAgIHR5cGVkZWYgY2hhciAoJkxhcmdlKVsyXTsKCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQywgdm9pZCAoQzo6KikgKCk+IGNsYXNzIFNGSU5BRSB7fTsgCgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEM+IHN0YXRpYyBTbWFsbCB0ZXN0IChTRklOQUU8QywgJkM6OmZvbz4gKikKICAgIHsgICAKICAgICAgICBzdGQ6OmNvdXQgPDwgIkhBUyIgPDwgc3RkOjplbmRsOwogICAgfSAgIAoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBDPiBzdGF0aWMgTGFyZ2UgdGVzdCAoLi4uKQogICAgeyAgIAogICAgICAgIHN0ZDo6Y291dCA8PCAiTk9UIEhBUyIgPDwgc3RkOjplbmRsOwogICAgfSAgIAp9OwoKY2xhc3MgQgp7CiAgICBwdWJsaWMgOgoKICAgIHZvaWQgZm9vICgpIHt9Cn07CgpjbGFzcyBEMSA6IHB1YmxpYyBCCnsKICBwcml2YXRlOiB2b2lkIGZvbyAoKSB7fSAvLyBvdmVycmlkZQp9OwoKY2xhc3MgRDIgOiBwdWJsaWMgQgp7CiAgICBwdWJsaWMgOgoKICAgIHVzaW5nIEI6OmZvbzsKfTsKCmNsYXNzIEQzIDogcHVibGljIEIge307IAoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCnRlbXBsYXRlPHR5cGVuYW1lIEMsIHZvaWQgKEM6OipwKSgpPgpzdHJ1Y3QgWHt9OwoKdGVtcGxhdGUgc3RydWN0IFg8RDEsJkQxOjpmb28+OyAgLy88LS0tIHByaXZhdGUgbWVtYmVycyBjYW4gYmUgdXNlZCBpbiBleHBsaWNpdCBpbnN0YW50aWF0aW9uCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCmludCBtYWluICgpCnsKICAvLyAgSGFzRm9vOjp0ZXN0PEI+KDApOwogIC8vICBIYXNGb286OnRlc3Q8RDE+KDApOwogIC8vICBIYXNGb286OnRlc3Q8RDI+KDApOwogIC8vICBIYXNGb286OnRlc3Q8RDM+KDApOwp9