Suppose I have the following:
#include <memory>
struct A { int x; };
class B {
B(int x, std::unique_ptr<A> a);
};
class C : public B {
C(std::unique_ptr<A> a) : B(a->x, std::move(a)) {}
};
If I understand the C++ rules about "unspecified order of function parameters" correctly, this code is unsafe. If the second argument to B's constructor is constructed first using the move constructor, then a now contains a nullptr and the expression a->x will trigger undefined behavior (likely segfault). If the first argument is constructed first, then everything will work as intended.
If this were a normal function call, we could just create a temporary:
auto x = a->x
B b{x, std::move(a)};
But in the class initialization list we don't have the freedom to create temporary variables.
Suppose I cannot change B, is there any possible way to accomplish the above? Namely dereferencing and moving a unique_ptr in the same function call expression without creating a temporary?
What if you could change B's constructor but not add new methods such as setX(int)? Would that help?
Thank you