Re[48]: offsetof() без UB
От: rg45 СССР  
Дата: 01.04.25 08:59
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Это конечно здорово, но это просто обёртка. Она не решает вопроса как такое передавать во внешнюю среду, или принимать из неё подобное.

_>Более того предыдущие указатели можно было сгенерировать руками если нет поддержки c++17. А тут только C++20.

Объект accessor<...> прекрасно заточен под передачу в качестве параметра. Если же ты имеешь в виду внешнюю среду, которая сама по себе сделана через жопу, тогда конечно, вокруг этого нужно будет сделать черезжопные обертки. Какие именно обёртки — будет продиктовано спецификой чережопной внешней среды.

_>ps: А что будет если надо обернуть функцию без параметров void A::g(); ?


Ты тут несколькими постами выше рассказывал, что концепты и констрейнты это легко и просто, а теперь задаешь такие глупые вопросы. Конечно же там следует добавить констрейнты. А также сделать форвардинг параметров. Я намеренно не сделал всего этого, чтобы максимально разгрузить код.

Более полный вариант мог бы выглядеть примерно так:

https://godbolt.org/z/3MEKsr4e3

#include <stdio.h>
#include <utility>

template <auto member>
requires (member != nullptr)
struct Accessor
{
   template <typename T>
   constexpr decltype(auto) operator()(T&& object) const
   requires (
      requires {std::forward<T>(object).*member;}
      and not requires {(std::forward<T>(object).*member)();})
   {
      return std::forward<T>(object).*member;
   }
   template <typename T, typename...X>
   constexpr decltype(auto) operator()(T&& object, X&&...x) const
   requires requires {(std::forward<T>(object).*member)(std::forward<X>(x)...);}
   {
      return (std::forward<T>(object).*member)(std::forward<X>(x)...);
   }
};
template <auto member> constexpr Accessor<member> accessor;

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

int main() {
   A a[1];
   auto fn = accessor<&A::fn>;
   auto x = accessor<&A::x>;
   auto get = accessor<&A::get>;

   printf("x=%d fn(20)=%d get=%d\n", x(*a), fn(*a, 20), get(*a));
}


При необходимости, разумеется, можно сделать и раздельные аксессоры для членов-функций и для членов-данных, это уже зависит от конкретных требований
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 01.04.2025 9:03 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.