Date: Wed, 22 Jan 2025 19:21:31 -0600
Hi,
As others mentioned, private and protected inheritance work (though they
don't make this a fully safe thing to do). Inheriting from a standard
library container is an anti-pattern and I'd much rather see extended
functionality, at least as far as member functions go, enabled through
extension methods or the proposed pipeline rewrite operator.
Cheers,
Jeremy
On Wed, Jan 22, 2025 at 9:29 AM Dennis Gusev via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> If you look up "inheriting from STL containers", the top results from SO
> and reddit all mention it being a bad practice since standard containers
> aren't designed to be inherited from.
>
> Specifically, they dont have virtual destructors so there's a risk of UB
> from deleting through pointer to base.
>
> Also if you override any existing member functions and accidentally pass
> your derived class to a function expecting a regular STL container, the
> original base class member functions will get called instead(not to mention
> potential object slicing).
>
> What if C++ had a way to publicly inherit from a class and also ban base
> class conversions to avoid potential usage pitfalls with something like
> this:
>
> class Base
>
> {
>
> public:
>
> void foo()
>
> {
>
> std::println("Base foo");
>
> }
>
> void bar()
>
> {
>
> std::println("Base bar");
>
> }
>
> };
>
> class PublicDerived : public Base
>
> {
>
> public:
>
> void foo()
>
> {
>
> std::println("PublicDerived foo");
>
> }
>
> };
>
> class ComposedDerived : composed Base // new type of inheritance
>
> {
>
> public:
>
> void foo()
>
> {
>
> std::println("ComposedDerived foo");
>
> }
>
> };
>
> void testFoo(Base& val)
>
> {
>
> val.foo();
>
> }
>
> int main()
>
> {
>
> PublicDerived publicDerived;
>
> publicDerived.foo(); // prints "PublicDerived foo"
>
> publicDerived.bar(); // accessible, prints "Base bar"
>
> testFoo(publicDerived); // uh oh, prints "Base foo" even though we
> have our own foo
>
> ComposedDerived composedDerived;
>
> composedDerived.foo(); // prints "ComposedDerived foo"
>
> composedDerived.bar(); // still accessible, prints "Base bar"
>
> testFoo(composedDerived) // doesn't compile, conversion to base
> forbidden
>
> return 0;
>
> }
>
> Has anything like this ever been proposed?
>
> Seems like it would address a common use case by making it possible to
> extend behavior of classes safely even if they weren't designed to be
> inherited from(i.e. no public virtual or protected nonvirtual destructor)
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
As others mentioned, private and protected inheritance work (though they
don't make this a fully safe thing to do). Inheriting from a standard
library container is an anti-pattern and I'd much rather see extended
functionality, at least as far as member functions go, enabled through
extension methods or the proposed pipeline rewrite operator.
Cheers,
Jeremy
On Wed, Jan 22, 2025 at 9:29 AM Dennis Gusev via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> If you look up "inheriting from STL containers", the top results from SO
> and reddit all mention it being a bad practice since standard containers
> aren't designed to be inherited from.
>
> Specifically, they dont have virtual destructors so there's a risk of UB
> from deleting through pointer to base.
>
> Also if you override any existing member functions and accidentally pass
> your derived class to a function expecting a regular STL container, the
> original base class member functions will get called instead(not to mention
> potential object slicing).
>
> What if C++ had a way to publicly inherit from a class and also ban base
> class conversions to avoid potential usage pitfalls with something like
> this:
>
> class Base
>
> {
>
> public:
>
> void foo()
>
> {
>
> std::println("Base foo");
>
> }
>
> void bar()
>
> {
>
> std::println("Base bar");
>
> }
>
> };
>
> class PublicDerived : public Base
>
> {
>
> public:
>
> void foo()
>
> {
>
> std::println("PublicDerived foo");
>
> }
>
> };
>
> class ComposedDerived : composed Base // new type of inheritance
>
> {
>
> public:
>
> void foo()
>
> {
>
> std::println("ComposedDerived foo");
>
> }
>
> };
>
> void testFoo(Base& val)
>
> {
>
> val.foo();
>
> }
>
> int main()
>
> {
>
> PublicDerived publicDerived;
>
> publicDerived.foo(); // prints "PublicDerived foo"
>
> publicDerived.bar(); // accessible, prints "Base bar"
>
> testFoo(publicDerived); // uh oh, prints "Base foo" even though we
> have our own foo
>
> ComposedDerived composedDerived;
>
> composedDerived.foo(); // prints "ComposedDerived foo"
>
> composedDerived.bar(); // still accessible, prints "Base bar"
>
> testFoo(composedDerived) // doesn't compile, conversion to base
> forbidden
>
> return 0;
>
> }
>
> Has anything like this ever been proposed?
>
> Seems like it would address a common use case by making it possible to
> extend behavior of classes safely even if they weren't designed to be
> inherited from(i.e. no public virtual or protected nonvirtual destructor)
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2025-01-23 01:21:43