Let's say, there is a simple polymorphic relationship:
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;};
And a storage class to hold them all together:
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();}
On both clang (10.0)
and MSVC (19.25)
this mcve works correctly, while gcc (9.3.0)
outputs:
derived_int: 5derived_string: 11111derived_int: -71963derived_string: 1
It seems that there's some kind of object life issue, as explicitly created variables don't cause any problems, but I cannot quite pinpoint it down.