Date: Mon, 8 Jul 2024 16:00:28 -0400
On Mon, Jul 8, 2024 at 1:55 PM Phil Endecott <
std_proposals_list_at_[hidden]> wrote:
>
> Can you make it work if there is no common base class? I.e.
>
> struct LeftCat { virtual ~LeftCat() = default; };
> struct RightCat { virtual ~RightCat() = default; };
> struct SiameseCat: LeftCat, RightCat {};
>
> int main() {
> SiameseCat sc;
> auto lc = static_cast<LeftCat*>(&sc); assert(lc);
>
That's an upcast, not a downcast.
> auto rc = down_cast<RightCat*>(&sc); assert(rc);
>
That's an upcast, not a downcast.
> auto lrc = down_cast<RightCat*>(lc); assert(!lrc); // dynamic_cast will
> sidecast here.
>
That's a sidecast, not a downcast.
The only ways "down" the hierarchy I presented are (Cat => LeftCat), (Cat
=> RightCat), (LeftCat => SiameseCat), and (RightCat => SiameseCat).
You can exclude non-down-casts with a plain old static_assert:
template<class To, class From>
To *downcast_to_leftcat(From *c) {
static_assert(std::is_base_of_v<From, To>, "Hey! I only do downcasts");
if (To *lc = dynamic_cast<To*>(c)) {
if (static_cast<From*>(lc) == c) {
return lc; // this was definitely a pure downcast
}
}
return nullptr;
}
–Arthur
std_proposals_list_at_[hidden]> wrote:
>
> Can you make it work if there is no common base class? I.e.
>
> struct LeftCat { virtual ~LeftCat() = default; };
> struct RightCat { virtual ~RightCat() = default; };
> struct SiameseCat: LeftCat, RightCat {};
>
> int main() {
> SiameseCat sc;
> auto lc = static_cast<LeftCat*>(&sc); assert(lc);
>
That's an upcast, not a downcast.
> auto rc = down_cast<RightCat*>(&sc); assert(rc);
>
That's an upcast, not a downcast.
> auto lrc = down_cast<RightCat*>(lc); assert(!lrc); // dynamic_cast will
> sidecast here.
>
That's a sidecast, not a downcast.
The only ways "down" the hierarchy I presented are (Cat => LeftCat), (Cat
=> RightCat), (LeftCat => SiameseCat), and (RightCat => SiameseCat).
You can exclude non-down-casts with a plain old static_assert:
template<class To, class From>
To *downcast_to_leftcat(From *c) {
static_assert(std::is_base_of_v<From, To>, "Hey! I only do downcasts");
if (To *lc = dynamic_cast<To*>(c)) {
if (static_cast<From*>(lc) == c) {
return lc; // this was definitely a pure downcast
}
}
return nullptr;
}
–Arthur
Received on 2024-07-08 20:00:41