#include <type_traits>
template<class Fty>
struct is_ptcmf : std::false_type{};
template<class C, class R, class... Args>
struct is_ptcmf<R (C::*)(Args...) const> : std::true_type{};
template<class C, class Fty, Fty F>
struct A{
static_assert(std::is_const<C>() == is_ptcmf<Fty>(), "Must pair const with const.");
};
struct X{
void foo(){}
void bar() const{}
};
template<class... Args>
void swallow(Args&&...){}
int main(){
A<X, decltype(&X::foo), &X::foo> a1;
A<X const, decltype(&X::bar), &X::bar> a2;
swallow(a1, a2);
//A<X const, decltype(&X::foo), &X::foo> a3; // error: static_assert
//A<X, decltype(&X::bar), &X::bar> a4; // error: static_assert
//swallow(a3, a4)
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGU8Y2xhc3MgRnR5PgpzdHJ1Y3QgaXNfcHRjbWYgOiBzdGQ6OmZhbHNlX3R5cGV7fTsKCnRlbXBsYXRlPGNsYXNzIEMsIGNsYXNzIFIsIGNsYXNzLi4uIEFyZ3M+CnN0cnVjdCBpc19wdGNtZjxSIChDOjoqKShBcmdzLi4uKSBjb25zdD4gOiBzdGQ6OnRydWVfdHlwZXt9OwoKdGVtcGxhdGU8Y2xhc3MgQywgY2xhc3MgRnR5LCBGdHkgRj4Kc3RydWN0IEF7CiAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX2NvbnN0PEM+KCkgPT0gaXNfcHRjbWY8RnR5PigpLCAiTXVzdCBwYWlyIGNvbnN0IHdpdGggY29uc3QuIik7Cn07CgpzdHJ1Y3QgWHsKICAgIHZvaWQgZm9vKCl7fQogICAgdm9pZCBiYXIoKSBjb25zdHt9Cn07Cgp0ZW1wbGF0ZTxjbGFzcy4uLiBBcmdzPgp2b2lkIHN3YWxsb3coQXJncyYmLi4uKXt9CgppbnQgbWFpbigpewogICAgQTxYLCBkZWNsdHlwZSgmWDo6Zm9vKSwgJlg6OmZvbz4gYTE7CiAgICBBPFggY29uc3QsIGRlY2x0eXBlKCZYOjpiYXIpLCAmWDo6YmFyPiBhMjsKICAgIHN3YWxsb3coYTEsIGEyKTsKICAgIAogICAgLy9BPFggY29uc3QsIGRlY2x0eXBlKCZYOjpmb28pLCAmWDo6Zm9vPiBhMzsgLy8gZXJyb3I6IHN0YXRpY19hc3NlcnQKICAgIC8vQTxYLCBkZWNsdHlwZSgmWDo6YmFyKSwgJlg6OmJhcj4gYTQ7IC8vIGVycm9yOiBzdGF0aWNfYXNzZXJ0CiAgICAvL3N3YWxsb3coYTMsIGE0KQp9