#include <cstdint>
#include <iostream>
#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature) \
template <typename U> \
class traitsName \
{ \
private: \
template<typename T, T> struct helper; \
template<typename T> \
static std::uint8_t check(helper<signature, &funcName>*); \
template<typename T> static std::uint16_t check(...); \
public: \
static \
constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \
}
DEFINE_HAS_SIGNATURE(has_ham_const, T::ham, void (T::*)() const);
struct foo {
void ham() {}
void ham() const {}
};
struct bar {
void ham() {}
};
static_assert(has_ham_const<foo>::value, "unexpected");
static_assert(!has_ham_const<bar>::value, "unexpected");
int main()
{
std::cout << has_ham_const<foo>::value << std::endl; // 1
std::cout << has_ham_const<bar>::value << std::endl; // 0
}
I2luY2x1ZGUgPGNzdGRpbnQ+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCiNkZWZpbmUgREVGSU5FX0hBU19TSUdOQVRVUkUodHJhaXRzTmFtZSwgZnVuY05hbWUsIHNpZ25hdHVyZSkgICAgICAgICAgICAgICBcCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBjbGFzcyB0cmFpdHNOYW1lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBwcml2YXRlOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVCwgVD4gc3RydWN0IGhlbHBlcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgc3RhdGljIHN0ZDo6dWludDhfdCBjaGVjayhoZWxwZXI8c2lnbmF0dXJlLCAmZnVuY05hbWU+Kik7ICAgICAgICAgICBcCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RhdGljIHN0ZDo6dWludDE2X3QgY2hlY2soLi4uKTsgICAgICAgICAgICAgICBcCiAgICBwdWJsaWM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgc3RhdGljICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgY29uc3RleHByIGJvb2wgdmFsdWUgPSBzaXplb2YoY2hlY2s8VT4oMCkpID09IHNpemVvZihzdGQ6OnVpbnQ4X3QpOyBcCiAgICB9CgpERUZJTkVfSEFTX1NJR05BVFVSRShoYXNfaGFtX2NvbnN0LCBUOjpoYW0sIHZvaWQgKFQ6OiopKCkgY29uc3QpOwoKCnN0cnVjdCBmb28gewogICAgdm9pZCBoYW0oKSB7fQogICAgdm9pZCBoYW0oKSBjb25zdCB7fQp9OwoKc3RydWN0IGJhciB7CiAgICB2b2lkIGhhbSgpIHt9Cn07CgpzdGF0aWNfYXNzZXJ0KGhhc19oYW1fY29uc3Q8Zm9vPjo6dmFsdWUsICJ1bmV4cGVjdGVkIik7CnN0YXRpY19hc3NlcnQoIWhhc19oYW1fY29uc3Q8YmFyPjo6dmFsdWUsICJ1bmV4cGVjdGVkIik7CgppbnQgbWFpbigpCnsKCXN0ZDo6Y291dCA8PCBoYXNfaGFtX2NvbnN0PGZvbz46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsgLy8gMQoJc3RkOjpjb3V0IDw8IGhhc19oYW1fY29uc3Q8YmFyPjo6dmFsdWUgPDwgc3RkOjplbmRsOyAvLyAwCn0=