#include <iostream>
#include <typeinfo>
#include <type_traits>
using namespace std;
struct A{
const int a;
int b;
};
template<typename T> struct tmpl;
template<typename Class, typename FT> struct tmpl<FT(Class::*)>{
static void f(){
if ( std::is_const< FT >::value ) {
cout<<"const as non const"<<endl;
} else {
cout<<"non const"<<endl;
}
}
};
//Try commenting this out, code compiles, both A::a and A::b instantiate the first template
/*template<typename Class, typename FT> struct tmpl<const FT(Class::*)>{
static void f(){
cout<<"const"<<endl;
}
};*/
int main(){
cout<<typeid(&A::a).name()<<endl; //prints "M1AKi"
tmpl<decltype(&A::a)>::f(); //prints "const"
cout<<typeid(&A::b).name()<<endl; //prints "M1Ai"
tmpl<decltype(&A::b)>::f(); //prints "non const"
//Let's do what it seems that can be done implicitly (providing only one template specialization) in an explicit way
int(A::*memb)= const_cast< int (A::*) >( &A::a );
cout<<typeid(memb).name()<<endl; //prints "M1Ai"
tmpl<decltype(memb)>::f(); //prints "non const"
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBBewogICAgY29uc3QgaW50IGE7CiAgICBpbnQgYjsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCB0bXBsOwoKdGVtcGxhdGU8dHlwZW5hbWUgQ2xhc3MsIHR5cGVuYW1lIEZUPiBzdHJ1Y3QgdG1wbDxGVChDbGFzczo6Kik+ewogICAgc3RhdGljIHZvaWQgZigpewogICAgICAgIGlmICggc3RkOjppc19jb25zdDwgRlQgPjo6dmFsdWUgKSB7CiAgICAgICAgICAgIGNvdXQ8PCJjb25zdCBhcyBub24gY29uc3QiPDxlbmRsOwoJfSBlbHNlIHsKICAgICAgICAgICAgY291dDw8Im5vbiBjb25zdCI8PGVuZGw7Cgl9CiAgICB9Cn07CgovL1RyeSBjb21tZW50aW5nIHRoaXMgb3V0LCBjb2RlIGNvbXBpbGVzLCBib3RoIEE6OmEgYW5kIEE6OmIgaW5zdGFudGlhdGUgdGhlIGZpcnN0IHRlbXBsYXRlCi8qdGVtcGxhdGU8dHlwZW5hbWUgQ2xhc3MsIHR5cGVuYW1lIEZUPiBzdHJ1Y3QgdG1wbDxjb25zdCBGVChDbGFzczo6Kik+ewogICAgc3RhdGljIHZvaWQgZigpewogICAgICAgIGNvdXQ8PCJjb25zdCI8PGVuZGw7CiAgICB9Cn07Ki8KCmludCBtYWluKCl7CiAgICBjb3V0PDx0eXBlaWQoJkE6OmEpLm5hbWUoKTw8ZW5kbDsgICAvL3ByaW50cyAiTTFBS2kiCiAgICB0bXBsPGRlY2x0eXBlKCZBOjphKT46OmYoKTsgICAgICAgICAvL3ByaW50cyAiY29uc3QiCiAgICBjb3V0PDx0eXBlaWQoJkE6OmIpLm5hbWUoKTw8ZW5kbDsgICAvL3ByaW50cyAiTTFBaSIKICAgIHRtcGw8ZGVjbHR5cGUoJkE6OmIpPjo6ZigpOyAgICAgICAgIC8vcHJpbnRzICJub24gY29uc3QiCiAgICAvL0xldCdzIGRvIHdoYXQgaXQgc2VlbXMgdGhhdCBjYW4gYmUgZG9uZSBpbXBsaWNpdGx5IChwcm92aWRpbmcgb25seSBvbmUgdGVtcGxhdGUgc3BlY2lhbGl6YXRpb24pIGluIGFuIGV4cGxpY2l0IHdheQogICAgaW50KEE6OiptZW1iKT0gY29uc3RfY2FzdDwgaW50IChBOjoqKSA+KCAmQTo6YSApOwogICAgY291dDw8dHlwZWlkKG1lbWIpLm5hbWUoKTw8ZW5kbDsgICAgLy9wcmludHMgIk0xQWkiCiAgICB0bXBsPGRlY2x0eXBlKG1lbWIpPjo6ZigpOyAgICAgICAgICAvL3ByaW50cyAibm9uIGNvbnN0Igp9Cg==