Предположим, что у меня есть следующее:
#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)) {}
};
Если я правильно понимаю правила С++ о "неуказанном порядке параметров функции", этот код небезопасен. Если второй аргумент конструктора B
строится сначала с использованием конструктора перемещения, то a
теперь содержит nullptr
, а выражение a->x
вызывает поведение undefined (вероятно, segfault). Если первый аргумент сконструирован первым, тогда все будет работать по назначению.
Если это был обычный вызов функции, мы могли бы просто создать временную:
auto x = a->x
B b{x, std::move(a)};
Но в списке инициализации класса мы не можем создавать временные переменные.
Предположим, что я не могу изменить B
, существует ли какой-либо возможный способ выполнения вышеуказанного? А именно разыменование и перемещение a unique_ptr
в одно и то же выражение вызова функции без создания временного?
Что делать, если вы можете изменить конструктор B
, но не добавить новые методы, такие как setX(int)
? Это поможет?
Спасибо