Vector of encapsulated references

I've currently got an interface (all functions pure virtual) called Base (which inherits from sf::Drawable and sf::Transformable), and several derived classes which inherit from base. One of these classes is a holder that contains a vector of classes which inherit from Base. As I can't just do std::vector<Base> as the contents of a vector are stored by value, I've tried to make an encapsulated reference to Base (called Element). It's a very simple class that inherits from Base so that it can use its functions and be used as a Base if needed. It also contains a single member variable, which is a reference to Base. I then made my holder class contain a vector of Elements but there have been tons of errors. I first had to make a new constructor that the vector needed, then an assignment operator then another constructor and now when I run it it causes it to crash and a backtrace says corrupted stack. Is there a standard way of doing this so that you can use polymorphic STL? The code is really quite long and in 9 files but I'll post it if needed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <memory>
#include <vector>

class Base
{
  public:
    virtual void identity() const
    {
        std::cout << "Base\n";
    }

    virtual ~Base() = default;
};

class Derived: public Base
{
  public:
    virtual void identity() const override
    {
        std::cout << "Derived\n";
    }
};

int main()
{
    //Approach 1: pointers
    std::vector<std::unique_ptr<Base>> foo;
    foo.emplace_back(std::make_unique<Base>());
    foo.emplace_back(std::make_unique<Derived>());
    foo.emplace_back(std::make_unique<Base>());
    for(const auto& p: foo)
        p->identity();
    std::cout << "\n\n";

    //Approach 2: reference wrappers
    std::vector<std::reference_wrapper<Base>> bar;
    Base i1, i3;
    Derived i2;
    bar.emplace_back(i1);
    bar.emplace_back(i2);
    bar.emplace_back(i3);
    for(Base& p: bar)
        p.identity();
    std::cout << "\n\n";
}
Base
Derived
Base


Base
Derived
Base

http://coliru.stacked-crooked.com/a/f9e014a13561daee
Last edited on
EDIT: deleted
Last edited on
Thank you. I was hoping there'd be a standard thing for this and that is exactly was I was looking for.
I've run into another issue with this now. I'm trying to pass an initializer_list of Base and Derived into a function. I've tried the following with and without the use of reference_wrapper in the initialzer_list template and with and without the std::ref.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <initializer_list>
#include <memory>
#include <vector>

class Base {
public:
    virtual void identity() const
    {
        std::cout << "Base\n";
    }

    virtual ~Base() = default;
};

class Derived: public Base {
public:
    virtual void identity() const override
    {
        std::cout << "Derived\n";
    }
};

void func ( std::initializer_list<std::reference_wrapper<Base>> objects )
{
    std::vector<std::reference_wrapper<Base>> bases;

    for ( auto& i : objects ) {
        bases.emplace_back ( i );
    }

    for ( auto& i : bases ) {
        i.get().identity();
    }
}

int main()
{
    Base i1, i3;
    Derived i2;
    func ( {std::ref(i1), std::ref(i2), std::ref(i3)} );
}


It either comes up with an error of it not being able to convert std::ref<Base>(i1), std::ref<Derived>(i2), std::ref<Base>(i3) from brace enclosed initializer list to std::initializer_list<std::reference_wrapper<Base>> or various errors about being unable to convert const Base (or sometimes const Base&) to Base&.
Last edited on
1
2
// func ( {std::ref(i1), std::ref(i2), std::ref(i3)} );
func ( { i1, i2, i3 } ); // implicit conversion from derived& to base& 

http://coliru.stacked-crooked.com/a/70a45e856c08d546
That's strange, I was sure I tried that. Thanks anyway, it must have been the one combination I missed.
Topic archived. No new replies allowed.