Rule ES.63: Don't slice is worded very strongly and decisively. It claims slicing is (almost always) undesirable and inappropriate: In all contexts, for all purposes. The motivation given, however, is that this "most often leads to errors".
So, my first point is that the rule itself concedes that this does not always lead to errors; and that we (or the rule authors) do not have a general argument about an arbitrary slicing scenario leading to errors, in itself. That is, given class B : public A { /*...*/ } and result_type foo(A), I do not believe we can show that calling foo(some_B) is problematic, unless we make significant assumptions about A and B. And the rule can only stand when qualified by these assumptions.
The second point regards the expression of intent, rule P.3 (edit:) and rule P1, "express ideas directly in code".
When a programmer says class B : public A, they are saying that "An object of type B is, in particular, an object of type A - and can be treated as such" (in other words, the use of public inheritance implies, or strongly insinuates, that the Liskov Substitution Principle applies.) An object of type A can be passed to a function which takes a parameter of type A, by value. Claiming that slicing is essentially forbidden means that we must ignore the expressed intent of the public inheritance, or rather, than we use public inheritance despite not having its actual intent.
If slicing is problematic for some class B : public A, then - why should B publicly inherit A? The inheritance could be protected, or private. That way, the programmer actually tells the compiler (and other programmers) whether the A making up B can or can't be sliced. But - that's a bit of a facetious point: We know such a convention is not what most programmers use in practice - because of convenience. If you inherit private or protected, you have to explicitly make available each and every bit of A again in B, which is quite tedious. So, the lazy thing to do is to just inherit publicly and rely on people ignoring the public inheritance: "I know I said my B is an A, but, come on, don't take it seriously... pretend my class is mis-defined and be extra-careful yourself".
I am not suggesting, that the guidelines switch position entirely, and demand that everyone change the way they code, and only use protected and private inheritance when slicing is problematic. But - ES.63 as it stands essentially forces people to adopt a broken interpretation of public inheritance - to ignore the expressed intent.
For these two reasons, I claim that the guideline should be relaxed from "don't slice" to something like "carefully consider the legitimacy of slicing" (this doesn't have to be the exact phrasing of course); and that the rule mention the potential pitfalls explicitly, but also remind readers about the meaning of public inheritance, suggesting that they also consider the possibility of private/protected inheritance if they are the class authors. The cases of zero-size / no-data-members objects can then be mentioned more briefly as an example of a legitimate use of slicing.
Rule ES.63: Don't slice is worded very strongly and decisively. It claims slicing is (almost always) undesirable and inappropriate: In all contexts, for all purposes. The motivation given, however, is that this "most often leads to errors".
So, my first point is that the rule itself concedes that this does not always lead to errors; and that we (or the rule authors) do not have a general argument about an arbitrary slicing scenario leading to errors, in itself. That is, given
class B : public A { /*...*/ }andresult_type foo(A), I do not believe we can show that callingfoo(some_B)is problematic, unless we make significant assumptions aboutAandB. And the rule can only stand when qualified by these assumptions.The second point regards the expression of intent, rule P.3 (edit:) and rule P1, "express ideas directly in code".
When a programmer says
class B : public A, they are saying that "An object of type B is, in particular, an object of type A - and can be treated as such" (in other words, the use of public inheritance implies, or strongly insinuates, that the Liskov Substitution Principle applies.) An object of typeAcan be passed to a function which takes a parameter of typeA, by value. Claiming that slicing is essentially forbidden means that we must ignore the expressed intent of the public inheritance, or rather, than we use public inheritance despite not having its actual intent.If slicing is problematic for some
class B : public A, then - why shouldBpublicly inheritA? The inheritance could beprotected, orprivate. That way, the programmer actually tells the compiler (and other programmers) whether theAmaking upBcan or can't be sliced. But - that's a bit of a facetious point: We know such a convention is not what most programmers use in practice - because of convenience. If you inheritprivateorprotected, you have to explicitly make available each and every bit ofAagain inB, which is quite tedious. So, the lazy thing to do is to just inherit publicly and rely on people ignoring the public inheritance: "I know I said myBis anA, but, come on, don't take it seriously... pretend my class is mis-defined and be extra-careful yourself".I am not suggesting, that the guidelines switch position entirely, and demand that everyone change the way they code, and only use
protectedandprivateinheritance when slicing is problematic. But - ES.63 as it stands essentially forces people to adopt a broken interpretation of public inheritance - to ignore the expressed intent.For these two reasons, I claim that the guideline should be relaxed from "don't slice" to something like "carefully consider the legitimacy of slicing" (this doesn't have to be the exact phrasing of course); and that the rule mention the potential pitfalls explicitly, but also remind readers about the meaning of public inheritance, suggesting that they also consider the possibility of private/protected inheritance if they are the class authors. The cases of zero-size / no-data-members objects can then be mentioned more briefly as an example of a legitimate use of slicing.