#include <type_traits>
#include <iostream>
struct C {};
int size (const C & c) {
std::cout << "global size!\n";
return 0;
}
template <typename B>
class has_size
{
// This type won't compile if the second template parameter isn't of type T,
// so I can put a function pointer type in the first parameter and the function
// itself in the second thus checking that the function has a specific signature.
template <typename T, T> struct TypeCheck;
typedef char Yes;
typedef struct { char dummy[2]; } No;
// A helper struct to hold the declaration of the function pointer.
// Change it if the function signature changes.
template <typename T> struct Size
{
typedef int (T::*fptr)(const C&);
};
template <typename T> static Yes HasSize(TypeCheck< typename Size<T>::fptr, &T::size >*);
template <typename T> static No HasSize(...);
public:
static bool const value = (sizeof(HasSize<B>(0)) == sizeof(Yes));
};
template <class B>
int callSize(B* obj, const C& c, typename std::enable_if<has_size<B>::value>::type* = 0)
{
obj->size(c);
}
template <class B>
int callSize(B*, const C& c, typename std::enable_if<!has_size<B>::value>::type* = 0)
{
return size(c);
}
struct B
{
int size () { /* ... */ };
template <class U> friend int ::callSize(U*, const C&, typename std::enable_if<has_size<U>::value>::type*);
template <class U> friend class has_size;
void doSomething (const C & c)
{
int x = ::callSize(this, c); // <----------- problem!
// ...
}
private:
#ifdef LOCAL_SIZE
int size (const C & c) {
std::cout << "local size!\n";
return 0;
}
#endif
};
int main() {
B b;
b.doSomething(C());
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8aW9zdHJlYW0+CgpzdHJ1Y3QgQyB7fTsKCmludCBzaXplIChjb25zdCBDICYgYykgewogICAgc3RkOjpjb3V0IDw8ICJnbG9iYWwgc2l6ZSFcbiI7CiAgICByZXR1cm4gMDsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEI+CmNsYXNzIGhhc19zaXplCnsKICAgIC8vIFRoaXMgdHlwZSB3b24ndCBjb21waWxlIGlmIHRoZSBzZWNvbmQgdGVtcGxhdGUgcGFyYW1ldGVyIGlzbid0IG9mIHR5cGUgVCwKICAgIC8vIHNvIEkgY2FuIHB1dCBhIGZ1bmN0aW9uIHBvaW50ZXIgdHlwZSBpbiB0aGUgZmlyc3QgcGFyYW1ldGVyIGFuZCB0aGUgZnVuY3Rpb24KICAgIC8vIGl0c2VsZiBpbiB0aGUgc2Vjb25kIHRodXMgY2hlY2tpbmcgdGhhdCB0aGUgZnVuY3Rpb24gaGFzIGEgc3BlY2lmaWMgc2lnbmF0dXJlLgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIFQ+IHN0cnVjdCBUeXBlQ2hlY2s7CgogICAgdHlwZWRlZiBjaGFyIFllczsKICAgIHR5cGVkZWYgc3RydWN0IHsgY2hhciBkdW1teVsyXTsgfSBObzsKCiAgICAvLyBBIGhlbHBlciBzdHJ1Y3QgdG8gaG9sZCB0aGUgZGVjbGFyYXRpb24gb2YgdGhlIGZ1bmN0aW9uIHBvaW50ZXIuCiAgICAvLyBDaGFuZ2UgaXQgaWYgdGhlIGZ1bmN0aW9uIHNpZ25hdHVyZSBjaGFuZ2VzLgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBTaXplCiAgICB7CiAgICAgICAgdHlwZWRlZiBpbnQgKFQ6OipmcHRyKShjb25zdCBDJik7CiAgICB9OwoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBzdGF0aWMgWWVzIEhhc1NpemUoVHlwZUNoZWNrPCB0eXBlbmFtZSBTaXplPFQ+OjpmcHRyLCAmVDo6c2l6ZSA+Kik7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RhdGljIE5vICBIYXNTaXplKC4uLik7CgpwdWJsaWM6CiAgICBzdGF0aWMgYm9vbCBjb25zdCB2YWx1ZSA9IChzaXplb2YoSGFzU2l6ZTxCPigwKSkgPT0gc2l6ZW9mKFllcykpOwp9Owp0ZW1wbGF0ZSA8Y2xhc3MgQj4KaW50IGNhbGxTaXplKEIqIG9iaiwgY29uc3QgQyYgYywgdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8aGFzX3NpemU8Qj46OnZhbHVlPjo6dHlwZSogPSAwKQp7CiAgICBvYmotPnNpemUoYyk7Cn0KdGVtcGxhdGUgPGNsYXNzIEI+CmludCBjYWxsU2l6ZShCKiwgY29uc3QgQyYgYywgdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8IWhhc19zaXplPEI+Ojp2YWx1ZT46OnR5cGUqID0gMCkKewogICAgcmV0dXJuIHNpemUoYyk7Cn0KCgpzdHJ1Y3QgQgp7CiAgICBpbnQgc2l6ZSAoKSB7IC8qIC4uLiAqLyB9OwoKICAgIHRlbXBsYXRlIDxjbGFzcyBVPiBmcmllbmQgaW50IDo6Y2FsbFNpemUoVSosIGNvbnN0IEMmLCB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxoYXNfc2l6ZTxVPjo6dmFsdWU+Ojp0eXBlKik7CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVT4gZnJpZW5kIGNsYXNzIGhhc19zaXplOwogICAgdm9pZCBkb1NvbWV0aGluZyAoY29uc3QgQyAmIGMpCiAgICB7CiAgICAgICBpbnQgeCA9IDo6Y2FsbFNpemUodGhpcywgYyk7IC8vIDwtLS0tLS0tLS0tLSBwcm9ibGVtIQogICAgICAgLy8gLi4uCiAgICB9CnByaXZhdGU6CiNpZmRlZiBMT0NBTF9TSVpFCiAgICBpbnQgc2l6ZSAoY29uc3QgQyAmIGMpIHsKICAgICAgIHN0ZDo6Y291dCA8PCAibG9jYWwgc2l6ZSFcbiI7CiAgICAgICByZXR1cm4gMDsKICAgICB9CiNlbmRpZgp9OwoKaW50IG1haW4oKSB7CiAgICBCIGI7CiAgICBiLmRvU29tZXRoaW5nKEMoKSk7Cn0=