C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Downcasting without Sidecasting

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Wed, 10 Jul 2024 14:19:27 +0100
On Tue, Jul 9, 2024 at 3:53 PM Phil Endecott wrote:
>
> It seems that rather
> than my original ask to distinguish up/down/side cases, I really needed to
> distinguish different degrees of separation in sidecasts!


I'm not entirely certain I understand your goal . . . but if I'm
barking up the right tree here, I've edited the implementation of
'dynamic_cast' so that it only does downcasts, and so here's your
previous program restricted to downcasts:

    https://godbolt.org/z/GbKGsrd67

Although I'm not 100% sure that's what you wanted.

And here it is copy-pasted:

#include <https://raw.githubusercontent.com/gcc-mirror/gcc/master/libstdc%2B%2B-v3/libsupc%2B%2B/tinfo.h>
#include <https://raw.githubusercontent.com/healytpk/down_cast/main/down_cast.hpp>

#include <cassert>
#include <iostream>

struct V { virtual ~V() = default; };
struct D { void foo() { std::cout << "foo"; } };

struct CV: V {};
struct DV: V, D {};

void foo(std::string_view msg, auto& v)
{
  std::cout << msg << ' ' << typeid(decltype(v)).name() << ' ';
  auto dp = down_cast<D*>(&v);
  if (dp) dp->foo();
  std::cout << '\n';
}
// (Also consider the case where the arg is V& v, not auto& v.)

void test1()
{
  std::cout << "====== Test1:\n";
  CV cv;
  DV dv;

  foo("cv", cv); // does nothing.
  foo("dv", dv); // calls D::foo.
}


struct Composed {
  CV cv;
  DV dv;
};

struct Inherited:
  CV,
  DV
{};

void test2()
{
  std::cout << "====== Test2:\n";
  Composed composed;
  Inherited inherited;

  foo("composed.cv", composed.cv); // does nothing.
  foo("composed.dv", composed.dv); // calls D::foo.

  foo("inherited CV", static_cast<CV&>(inherited)); // Unexpectedly
calls D::foo.
  foo("inherited DV", static_cast<DV&>(inherited)); // Calls D::foo.
}

int main()
{
  test1();
  test2();
}

Received on 2024-07-10 13:19:41