Информация об изменениях

Сообщение Re: сравнение member fucntion pointers от 31.03.2020 13:54

Изменено 31.03.2020 14:00 kov_serg

Re: сравнение member fucntion pointers
Здравствуйте, niXman, Вы писали:

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; }
        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::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(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 с названиями функций.
#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;
}