C++ Weekly - Ep 264 - Covariant Return Types and Covariant Smart Pointers

preview_player
Показать описание
☟☟ Awesome T-Shirts! Sponsors! Books! ☟☟

T-SHIRTS AVAILABLE!

WANT MORE JASON?

SUPPORT THE CHANNEL

GET INVOLVED

JASON'S BOOKS

► C++23 Best Practices

► C++ Best Practices

JASON'S PUZZLE BOOKS

► Object Lifetime Puzzlers Book 1

► Object Lifetime Puzzlers Book 2

► Object Lifetime Puzzlers Book 3

► Copy and Reference Puzzlers Book 1

► Copy and Reference Puzzlers Book 2

► Copy and Reference Puzzlers Book 3

► OpCode Puzzlers Book 1


RECOMMENDED BOOKS

AWESOME PROJECTS

O'Reilly VIDEOS

Рекомендации по теме
Комментарии
Автор

First thing that comes to mind as a replacement of the static_asserts is concepts. I'm sure you can write a requires to check this

ruadeil_zabelin
Автор

Watching you try and figure something out in C++ at fast forward speed is very entertaining.

Ariccio
Автор

I would really love to see this added to the standard. It could help avoid static_pointer_cast in many situations

ultimatesoup
Автор

could you make a video about coroutines & fibers and their use cases?

fixpontt
Автор

Cool idea. In general, containers cannot be covariant unless they are immutable (someone could pass container of derived to function taking container of base which adds/sets an element of base type in the container, boom), so you would have to hide the ability for someone to ever set or null out the shared_ptr, or else make the shared_ptr member const.

James-kgfp
Автор

You can emulate covariant smart pointers with this pattern:
#include <memory>

class Base
{
public:
std::shared_ptr<Base> get_child(){
return get_child_impl();
}
private:
virtual std::shared_ptr<Base> get_child_impl() =0;
};


class Derived: public Base
{
public:
std::shared_ptr<Derived> get_child(){
return child;
}
private:
std::shared_ptr<Base> get_child_impl()override{ return get_child();}
std::shared_ptr<Derived> child;
};

fecjanky
Автор

But Covariant_Pointer<Base> is just an empty class. So given e.g. reference to struct Base I have no way of dereferencing what is pointed to by Covariant_Pointer<Base> returned from get_child(). I would have to upcast it to Covariant<Derived, Base> to get access to value field, but the whole point of covariant types is that I can use it without knowing what is this derived class.

WladcaKsomsou
Автор

If I am not mistaken, I think the proposed solution works only if you return the pointer object by reference, which means that the object must exist somewhere outside of the scope of the function (in your example, it is a member variable). It is not as flexible unfortunately as built-in covariant return types that can return "raw pointers by value". For example, I don't think you could use that technique for a covariant factory function returning a newly-allocated object, but I may be mistaken.

VincentZalzal
Автор

So, the question is, how to specify the "self type"? I mean, if it's possible to write
struct Base{
virtual THIS_TYPE* get_child()=0;}
and in derived class, this THIS_TYPE changes itself to the new type.
Do we have this feature in cpp?

hanyanglee
Автор

An interesting construct I've come across while working on some foreign code is a template base class that receives the derived type as template parameter. That way, getChild() can return the template parameter, thusly returning a derived object.

BatManWayneCorp
Автор

Can someone explain what the hell happened with those metaprogramming type struct declarations at 5:37? My head didn't get around that fully.
Any easy explanation will be appreciated.

praveen
Автор

Would it be possible to get concepts to do the work you were trying to do with static_assert?

Omnifarious
Автор

C# 'in' and 'out' covariance specifiers are nice.

AlekseiGuzev
Автор

You can probably do it if you change the static assertion to a requires clause

ultimatesoup
Автор

I met this problem several years ago and solved it like this at first. But it still requires reference. So I don't know how to make stack-wrapped object work exactly the same with raw pointer. And finally, I compromised and make the method of derive class return smart pointer of base class.

kiesun
Автор

Did you try to add a constructor inside covariant_pointer and put static_assert there?

antagonista
Автор

So what is the point of covariant return types anyway? Like the actual practical use case

zeez
Автор

It looks to me that this technique only works if you return a pointer or a reference to Covariant_Pointer type. What is the gain compared to returning directly a pointer or reference to the actual ?

ericLemanissier
Автор

But you return your covariant pointer by reference.
If you return it by value it seems won't compile as it did with shared_pointer.

danielmilyutin
Автор

How do these work with multiple inheritance? Are there two functions, one for calling directly and one to go in the vtable, since the Base* and the Derived* are different bits?

aDifferentJT