Каков пример реального мира для "умного указателя на члена"?

Чтобы прояснить возможную двусмысленность приоритета на английском языке: мы берем "умный (указатель на член)", а не "(умный указатель) на член".

Я бы определил умный указатель на член как класс X с перегруженным operator ->* (T* lhs, X rhs).

В своей статье "Реализующий оператор → * для интеллектуальных указателей" Скотт Майерс лишь кратко затрагивает умный указатель на член, потому что тогда (1999) конкретная проблема была достаточно сложной для указателя raw для участника (сторона примечания: последняя решена элегантно с lambdas здесь).

В любом случае Скотт Майерс пишет в сноске:

Вскоре после написания проекта этой статьи один из моих консультаций клиенты показали мне проблему, которая, естественно, решалась умными указателями на участников. Я тоже был удивлен.

Я попытался найти пример такого естественного умного указателя на член. Но я не мог ни придумать ничего, ни поиска в Интернете, чтобы узнать, что я искал.

Вы знаете какой-либо реальный мир "умный указатель на член"?

ИЗМЕНИТЬ: Я не ищу никакой перегрузки ->* (как это делают некоторые EDSL). Направляя примеры с семантикой, которые напоминают встроенный ->*, мое определение выше явно требует, чтобы lhs был необработанным указателем.

Ответ 1

У вас есть механизм компоновки, который должен работать с 90-градусным вращением (перестановка по высоте и ширине).

Используя интеллектуальные указатели элементов, вы можете сделать (foo->*x) и (foo->*y) значение подкачки. Те же умные x и y могут работать с различными несвязанными типами данных (прямоугольники, точки, векторы), даже по типам, которых вы не являетесь.

template<class F>
struct smart_pm_t {
  F f;
  template<class T>
  friend decltype(auto) operator->*(T* t, smart_pm_t const& self ) {
    return self.f(t);
  }
};

template<class F>
smart_pm_t<F> smart_pm( F f ) { return {std::move(f)}; }

auto x = smart_pm( [](auto* t)->decltype(auto) noexcept { return t->x; } );
auto y = smart_pm( [](auto* t)->decltype(auto) noexcept { return t->y; } );

и мы можем с ними полюбоваться.

do_layout( data, x, y );

против

do_layout( data, y, x );

решает проблему горизонтально или вертикально.

Это фактический (упрощенный) вариант использования в фактическом производственном коде, который уменьшил дублирование кода и вычистил целую кучу ошибок, потому что нам нужно было только один раз исправить код.

Правильный указатель элемента правой руки имел проблему, что нам пришлось бы передать целый набор указателей элементов, по одному на тип, который работает с левой стороны.

Фактически мы написали указатель на полиморфный член времени компиляции.