C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Extend std::type_info with more information

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 11 Apr 2024 13:42:31 -0400
On Thu, Apr 11, 2024 at 12:46 PM Phil Endecott via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> Let me describe the situation in which I discovered a need for a
> std::any -like type that would allow me to cast to a base class:
>
> Consider a std::any used represent something like a "current selection" in
> a GUI application.
>
> I have a variety of abstract base classes ("interfaces") that the
> application's objects may implement, including whatever is currently
> stored in the selection.
>
> User interface objects (such as menu items) may want to be enabled or
> disabled depending on whether their action is appropriate for the current
> selected object, and then invoke the action through the base class.
>
> So for example I may have an abstract base class like this:
>
> class Alignable
> {
> public:
> enum Alignment { left, center, right };
> virtual void align(Alignment a) = 0;
> };
>
> Then I have concrete derived classes like this:
>
> class Paragraph: public Alignable, ....
>
> Then I have an alignment menu, which does something like this:
>
> align_menu.enabled =
> any_base_cast<Alignable>(&current_selection) != nullptr;
>
> align_menu.left.on_tap =
> any_base_cast<Alignable>(&current_selection) -> align(left);
> ...
>

The Classic C++ way to do this is to define an abstract base class
"Selectable" representing things-that-can-be-selected.
That is, I assume it's not part of your software design to allow
`current_selection` to hold an `int` or a `std::string`, but only some kind
of application object (traditionally known as a "widget" or "window"). So
we have, like,

class Widget { virtual ~Widget() = default; };
class Selectable : public virtual Widget {}; // actually this inheritance
isn't even being used here; remove it if you don't like dreaded diamonds
class Alignable : public virtual Widget {};
class TextElement : public Alignable, public Selectable {};

Selectable *current_selection;
align_menu.enabled = (dynamic_cast<Alignable*>(current_selection) !=
nullptr);

This doesn't involve anything `any`-like; it's just Classic C++ OOP. It
might well benefit from some RAII (smart-pointer) wrappers, but I don't
think *this specific application* benefits from type erasure at all.

–Arthur

Received on 2024-04-11 17:42:45