#include <iostream>
#include <vector>
#include <functional> // ****

struct object
{
    virtual ~object() {}
    virtual void display() const = 0 ;
};

struct weapon : object
{
    explicit weapon( std::string n ) : name(n) {}

    virtual void display() const override { std::cout << "weapon: " << name << '\n' ; }

    const std::string name ;
    // ...
};

struct consumable : object
{
    explicit consumable( std::string d ) : desc(d) {}

    virtual void display() const override { std::cout << "consumable: " << desc << '\n' ; }

    const std::string desc ;
    // ...
};


int main()
{
    weapon BronzeSword ( "bronze sword" ) ;
    weapon IronSword ( "iron sword" ) ;
    consumable MinorHealth ( "minor health" ) ;
    consumable Bread ( "bread" ) ;

    {
        std::vector< object* > inventory ; // option one

        inventory.push_back( &BronzeSword ) ;
        inventory.push_back( &IronSword ) ;
        inventory.push_back( &MinorHealth ) ;
        inventory.push_back( &Bread ) ;

        for( auto ptr : inventory ) ptr->display() ;
    }

    std::cout << "\n---------------------------\n\n" ;

    {
        std::vector< std::reference_wrapper<object> > inventory ; // option two

        inventory.push_back( BronzeSword ) ;
        inventory.push_back( IronSword ) ;
        inventory.push_back( MinorHealth ) ;
        inventory.push_back( Bread ) ;

        for( const auto& wrapper : inventory ) wrapper.get().display() ;
    }
}
