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();
}
>
> 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