#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"
}
