Допустим, существует простое полиморфное c отношение:
class base {
public:
void update() const { updater(); }
void accept(visitor const &visitor) {
visitor_acceptor(visitor);
}
protected:
base(std::function<void()> const &updater,
std::function<void(visitor const &)> const &visitor_acceptor)
: updater(updater), visitor_acceptor(visitor_acceptor) {}
protected:
std::function<void()> updater;
std::function<void(visitor const &)> visitor_acceptor;
};
class derived_int : public base {
public:
derived_int() : base(
[this]() { ++value; },
[this](visitor const &visitor) { visitor(value); }
), value(0) {}
protected:
int value;
};
class derived_string : public base {
public:
derived_string() : base(
[this]() { value += '1'; },
[this](visitor const &visitor) { visitor(value); }
), value("") {}
protected:
std::string value;
};
и класс хранения для хранения их всех вместе:
class storage {
public:
void add(base const &input) { pointers.emplace_back(std::make_unique<base>(input)); }
void add(base &&input) { pointers.emplace_back(std::make_unique<base>(std::move(input))); }
void update() {
for (auto &ptr : pointers)
ptr->update();
}
void print() {
visitor printer;
for (auto &ptr : pointers)
ptr->accept(printer);
}
private:
std::vector<std::unique_ptr<base>> pointers;
};
main:
int main() {
storage s;
derived_int temp1;
derived_string temp2;
s.add(temp1);
s.add(temp2);
s.add(derived_int{});
s.add(derived_string{});
for (size_t i = 0; i < 5; i++)
s.update();
s.print();
}
На clang (10.0)
и MSVC (19.25)
этот mcve работает правильно, а gcc (9.3.0)
выводит:
derived_int: 5
derived_string: 11111
derived_int: -71963
derived_string: 1
Кажется, что существует какая-то проблема жизни объекта , поскольку явно созданные переменные не вызывают никаких проблем, но я не могу точно определить их.