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

Сообщение Re[46]: offsetof() без UB от 31.03.2025 21:48

Изменено 31.03.2025 22:00 rg45

Re[46]: offsetof() без UB
Здравствуйте, kov_serg, Вы писали:

_>Ну хз. Мне такие указатели гораздо удобнее чем то что в C++ нагородили


_>https://godbolt.org/z/Y7xMsE6qo

  Оригинальный пример
#include <utility>

template<class P,auto field>class mptr_t {
    template<class A,class B> static A helper(A B::*);
public:
    typedef decltype(helper(field)) field_t; typedef P class_t;
    typedef field_t* (*type)(class_t*);
    static  field_t* value(class_t* p) { return &(p->*field); }
};

template<class P,auto mfn>class mfn_t {
    template<class T> struct helper;
    template<class C,class R,class...Args> struct helper<R(C::*)(Args...)> {
        typedef R result_t; typedef R (*type)(C*,Args...);
        template<class FP,auto m>static R value(FP* p,Args... args) {
            return (p->*m)(std::forward<Args>(args)...);
        }
    };
    using h=helper<decltype(mfn)>;
public:
    typedef P class_t; typedef typename h::result_t result_t;
    typedef typename h::type type;
    constexpr static type value=h::template value<P,mfn>;
};

template<class P,auto m> inline constexpr typename mptr_t<P,m>::type 
mptr = mptr_t<P,m>::value;
template<class P,auto m> inline constexpr typename mfn_t<P,m>::type 
mfn = mfn_t<P,m>::value;

//------------------------------------------------------------------------------

struct A {
    int x=10;
    virtual int fn(int y) { return x+y; }
};

#include <stdio.h>
int main(int argc, char **argv) {
    A a[1];
    auto pfn=mfn<A,&A::fn>;
    auto px=mptr<A,&A::x>;
    printf("px=%p pfn=%p\n",px,pfn);
    printf("x=%d fn(20)=%d\n",*px(a),pfn(a,20));
    return 0;
}


Мда уж. Демонстрация того, что даже самые простые вещи можно делать черз жопу.

Хотя, казалось бы, чего уж проще:

https://godbolt.org/z/qv4T51Wcr

#include <stdio.h>

template <auto member>
struct Accessor
{
   constexpr decltype(auto) operator()(auto&& object) const {
      return object.*member;
   }
   constexpr decltype(auto) operator()(auto&& object, auto&&...args) const {
      return (object.*member)(args...);
   }
};
template <auto member> constexpr Accessor<member> accessor;

struct A {
   int x = 10;
   virtual int fn(int y) { return x + y; }
};

int main() {
   A a[1];
   auto fn = accessor<&A::fn>;
   auto x = accessor<&A::x>;
   printf("x=%d fn(20)=%d\n", x(*a), fn(*a, 20));
}
Re[46]: offsetof() без UB
Здравствуйте, kov_serg, Вы писали:

_>Ну хз. Мне такие указатели гораздо удобнее чем то что в C++ нагородили


_>https://godbolt.org/z/Y7xMsE6qo

  Оригинальный пример
#include <utility>

template<class P,auto field>class mptr_t {
    template<class A,class B> static A helper(A B::*);
public:
    typedef decltype(helper(field)) field_t; typedef P class_t;
    typedef field_t* (*type)(class_t*);
    static  field_t* value(class_t* p) { return &(p->*field); }
};

template<class P,auto mfn>class mfn_t {
    template<class T> struct helper;
    template<class C,class R,class...Args> struct helper<R(C::*)(Args...)> {
        typedef R result_t; typedef R (*type)(C*,Args...);
        template<class FP,auto m>static R value(FP* p,Args... args) {
            return (p->*m)(std::forward<Args>(args)...);
        }
    };
    using h=helper<decltype(mfn)>;
public:
    typedef P class_t; typedef typename h::result_t result_t;
    typedef typename h::type type;
    constexpr static type value=h::template value<P,mfn>;
};

template<class P,auto m> inline constexpr typename mptr_t<P,m>::type 
mptr = mptr_t<P,m>::value;
template<class P,auto m> inline constexpr typename mfn_t<P,m>::type 
mfn = mfn_t<P,m>::value;

//------------------------------------------------------------------------------

struct A {
    int x=10;
    virtual int fn(int y) { return x+y; }
};

#include <stdio.h>
int main(int argc, char **argv) {
    A a[1];
    auto pfn=mfn<A,&A::fn>;
    auto px=mptr<A,&A::x>;
    printf("px=%p pfn=%p\n",px,pfn);
    printf("x=%d fn(20)=%d\n",*px(a),pfn(a,20));
    return 0;
}


Мда уж. Демонстрация того, что даже самые простые вещи можно делать черeз жопу.

Хотя, казалось бы, чего уж проще:

https://godbolt.org/z/qv4T51Wcr

#include <stdio.h>

template <auto member>
struct Accessor
{
   constexpr decltype(auto) operator()(auto&& object) const {
      return object.*member;
   }
   constexpr decltype(auto) operator()(auto&& object, auto&&...args) const {
      return (object.*member)(args...);
   }
};
template <auto member> constexpr Accessor<member> accessor;

struct A {
   int x = 10;
   virtual int fn(int y) { return x + y; }
};

int main() {
   A a[1];
   auto fn = accessor<&A::fn>;
   auto x = accessor<&A::x>;
   printf("x=%d fn(20)=%d\n", x(*a), fn(*a, 20));
}