Сообщение Re: сравнение member fucntion pointers от 31.03.2020 13:54
Изменено 31.03.2020 14:01 kov_serg
Re: сравнение member fucntion pointers
Здравствуйте, niXman, Вы писали:
X>привет!
...
X>обратите внимание на функцию get_stat(). эта финукция генерится препроцессором, т.е. не руками. но вопрос не в этом. вопрос в красивости =)
X>можно ли как-то это сделать по-красивей и переносимей?
X>в масив-то не положишь их — сигнатуры могут быть разными...
X>в switch() — тоже, но не из-за сигнатур.
X>какие идеи?
Я конечно понимаю что цель это просто сбор статистики по функциям. Но так как в C++ соверешшно у@$&щные указатели на члены класса
Я бы использовал другие идентификаторы, напимер enum с названиями функций.
X>привет!
...
X>обратите внимание на функцию get_stat(). эта финукция генерится препроцессором, т.е. не руками. но вопрос не в этом. вопрос в красивости =)
X>можно ли как-то это сделать по-красивей и переносимей?
X>в масив-то не положишь их — сигнатуры могут быть разными...
X>в switch() — тоже, но не из-за сигнатур.
X>какие идеи?
Я конечно понимаю что цель это просто сбор статистики по функциям. Но так как в C++ соверешшно у@$&щные указатели на члены класса
Я бы использовал другие идентификаторы, напимер enum с названиями функций.
#include <stdio.h>
struct Info {
double x;
Info() { x=0; }
};
struct Scope{ Scope(Info& info) { info.x=info.x+1; } };
struct A {
struct Member {
enum ID { UB, fn_void,fn1,fn2,fn_int, MAX };
template<class T> static int id(T t) {
if (cmp(t,static_cast<void(A::*)()>(&A::fn))) return fn_void;
if (cmp(t,&A::fn1)) return fn1;
if (cmp(t,&A::fn2)) return fn2;
if (cmp(t,static_cast<void(A::*)(int)>(&A::fn))) return fn_int;
return UB;
}
static int id(enum ID id) { return id; }
static int id(int id) { return id>UB || id<MAX ? id : UB; }
template<class T> Info& operator[] (T t) { return info[id(t)]; }
private:
Info info[MAX];
template<class T> static bool cmp(T a,T b) { return a==b; }
template<class A,class B> static bool cmp(A a,B b) { return false; }
} member;
void fn() { Scope scope(member[Member::fn_void]);
}
void fn1() { Scope scope(member[Member::fn1]);
}
void fn2() { Scope scope(member[Member::fn2]);
}
void fn(int) { Scope scope(member[Member::fn_int]);
}
};
int main(int argc, char const *argv[]) {
A a;
a.member[&A::fn1].x=3.14;
a.member[A::Member::fn_void].x=1.41;
a.member[A::Member::fn_int].x=2.71;
printf("id=%d x=%g\n",A::Member::fn1 , a.member[A::Member::fn1].x );
printf("id=%d x=%g\n",A::Member::fn2 , a.member[A::Member::fn2].x );
printf("id=%d x=%g\n",A::Member::fn_int , a.member[A::Member::fn_int].x );
printf("id=%d x=%g\n",A::Member::fn_void , a.member[A::Member::fn_void].x );
printf("id=%d x=%g\n",A::Member::id(&A::fn1) , a.member[&A::fn1].x );
printf("id=%d x=%g\n",A::Member::id(&A::fn2) , a.member[&A::fn2].x );
printf("id=%d x=%g\n",A::Member::id(static_cast<void(A::*)(int)>(&A::fn)) , a.member[static_cast<void(A::*)(int)>(&A::fn)].x );
printf("id=%d x=%g\n",A::Member::id(static_cast<void(A::*)()>(&A::fn)) , a.member[static_cast<void(A::*)()>(&A::fn)].x );
return 0;
}
Re: сравнение member fucntion pointers
Здравствуйте, niXman, Вы писали:
X>привет!
...
X>обратите внимание на функцию get_stat(). эта финукция генерится препроцессором, т.е. не руками. но вопрос не в этом. вопрос в красивости =)
X>можно ли как-то это сделать по-красивей и переносимей?
X>в масив-то не положишь их — сигнатуры могут быть разными...
X>в switch() — тоже, но не из-за сигнатур.
X>какие идеи?
Я конечно понимаю что цель это просто сбор статистики по функциям. Но так как в C++ соверешшно у@$&щные указатели на члены класса
Я бы использовал другие идентификаторы, напимер enum с названиями функций.
X>привет!
...
X>обратите внимание на функцию get_stat(). эта финукция генерится препроцессором, т.е. не руками. но вопрос не в этом. вопрос в красивости =)
X>можно ли как-то это сделать по-красивей и переносимей?
X>в масив-то не положишь их — сигнатуры могут быть разными...
X>в switch() — тоже, но не из-за сигнатур.
X>какие идеи?
Я конечно понимаю что цель это просто сбор статистики по функциям. Но так как в C++ соверешшно у@$&щные указатели на члены класса
Я бы использовал другие идентификаторы, напимер enum с названиями функций.
#include <stdio.h>
struct Info {
double x;
Info() { x=0; }
};
struct Scope{ Scope(Info& info) { info.x=info.x+1; } };
struct A {
struct Member {
enum ID { UB, fn_void,fn1,fn2,fn_int, MAX };
template<class T> static int id(T t) {
if (cmp(t,static_cast<void(A::*)()>(&A::fn))) return fn_void;
if (cmp(t,&A::fn1)) return fn1;
if (cmp(t,&A::fn2)) return fn2;
if (cmp(t,static_cast<void(A::*)(int)>(&A::fn))) return fn_int;
return UB;
}
static int id(enum ID id) { return id; }
static int id(int id) { return id>UB && id<MAX ? id : UB; }
template<class T> Info& operator[] (T t) { return info[id(t)]; }
private:
Info info[MAX];
template<class T> static bool cmp(T a,T b) { return a==b; }
template<class A,class B> static bool cmp(A a,B b) { return false; }
} member;
void fn() { Scope scope(member[Member::fn_void]);
}
void fn1() { Scope scope(member[Member::fn1]);
}
void fn2() { Scope scope(member[Member::fn2]);
}
void fn(int) { Scope scope(member[Member::fn_int]);
}
};
int main(int argc, char const *argv[]) {
A a;
a.member[&A::fn1].x=3.14;
a.member[A::Member::fn_void].x=1.41;
a.member[A::Member::fn_int].x=2.71;
printf("id=%d x=%g\n",A::Member::fn1 , a.member[A::Member::fn1].x );
printf("id=%d x=%g\n",A::Member::fn2 , a.member[A::Member::fn2].x );
printf("id=%d x=%g\n",A::Member::fn_int , a.member[A::Member::fn_int].x );
printf("id=%d x=%g\n",A::Member::fn_void , a.member[A::Member::fn_void].x );
printf("id=%d x=%g\n",A::Member::id(&A::fn1) , a.member[&A::fn1].x );
printf("id=%d x=%g\n",A::Member::id(&A::fn2) , a.member[&A::fn2].x );
printf("id=%d x=%g\n",A::Member::id(static_cast<void(A::*)(int)>(&A::fn)) , a.member[static_cast<void(A::*)(int)>(&A::fn)].x );
printf("id=%d x=%g\n",A::Member::id(static_cast<void(A::*)()>(&A::fn)) , a.member[static_cast<void(A::*)()>(&A::fn)].x );
return 0;
}