On Tue, May 7, 2024 at 3:46?AM Arthur OrDwyer via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
>This code is buggy. But it also violates the Rule of Zero: you wrote code
>*manually*, and you got it *wrong*, so naturally it's also going to do
>the wrong thing.
Think about it, the code you wrote class by class is absolutely correct, I mean not breaking any rules. But some code sequences are wrong, which means I have to focus on combinations of codes, which is very bad.
>And it leads us to a specific workaround in this case. If we really must
>take control of `Derived`'s value semantics ? if we can't delegate them to
>some other "resource-management type" ? then we must take the
>responsibility for ensuring that the correct code is run for each thing
>that we manually do.
We can do it automatically for the user.
==============
>I meant that `base(that)` should be `base(std::ref(that))`, and
>`base`'s constructor should be changed accordingly.
`base(std::ref(that))` solves the problem via introducing another level of abstraction.
And `std::ref` still can be instantiated with `T`(for example struct derived) as a reference type.
struct base {
public : base() {}
template <typename T> base(T x) {}
};
struct derived : public base {
public: derived() {}
derived(derived& that): base(std::ref(that)) {}
};
int main() {
derived d1;
derived d2 = d1;
return 0;
}