How i can deposit vectors with different objects?

Hello.

I my code i have a base struct ...
Then others structs made ...

1
2
3
4
5
6
7
8
9
10
11
12
13
struct base{};
struct a1 : base
{
   int a;
    int b;
};
vector<a1>v1;
struct a2 : base
{
   int a;
    int b;
};
vector<a2>v2;

Now i must deposit all these containers(maybe & of containers) in another vector...

How i can do that? Can i write

1
2
3
vector<vector<base*> > all;
all.push_back(&v1);
all.push_back(&v2);








Well your approach would work if you would use:

1
2
3
4
5
6
vector<base *> v1, v2;

// ...

all.push_back(v1); // no addresses
all.push_back(v2);


I don't know if I should suggest smart pointers... storing plain pointers (to dynamic memory) in containers is generally a bad idea.
Last edited on
v1 is a container of a1 struct and v2 is a container of a2 struct.
The objects of type a1 and a2 are many.
I must have access at two conatainers, v1 and v2 from another container, the all.

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
47
48
#include <iostream>
#include <vector>

using namespace std;

struct base {};

vector<vector<base*> > all;

struct a1 : base
{
    int a;
    int b;
};
vector<base>v1;
struct a2 : base
{
    int a;
    int b;
};
vector<base>v2;

int main()
{
    a1 i;
    i.a=2;
    i.b=3;
    v1.push_back(i);
    a1 j;
    j.a=2;
    j.b=3;
    v1.push_back(j);

    a2 k;
    k.a=2;
    k.b=3;
    v2.push_back(k);

    a2 l;
    l.a=2;
    l.b=3;
    v2.push_back(l);


    all.push_back(v1);

    return 0;
}


In all.push_back(v1); i have error ...

main.cpp|45|error: no matching function for call to 'std::vector<std::vector<base*> >::push_back(std::vector<base>&)'|


Ok i found it ...

vector<vector<base> > all;

without *

Thanks for reply.

Jim
Ok i found it ...

vector<vector<base> > all;

without *

That's a bad idea. When your objects are copied into their vectors, the copies will only be of type base, not a1 or a2.

If you use vectors of base*, then although the pointer will be a base*, the actual objects being pointed to will be of the correct type.
Last edited on
While perhaps not a very elegant solution, you can do this by making your vector store pointers to arbitrary data, along with some kind of data that you can use to identify what kind of vector the pointer points to.

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
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct Cat {
    string name;
    int age;
};

struct Pencil {
    float sharpness;
    float length;
};

struct ListOfThings {
    enum Type {
	CatList,
	PencilList
    }type;
    void *listData;
};

int main()
{
    vector<Cat> cats;
    cats.push_back({"Joey", 4});
    cats.push_back({"Mitzi", 6});
    cats.push_back({"Garfield", 10});
    vector<Pencil> pencils;
    pencils.push_back({1.0f, 17.6f});
    pencils.push_back({0.6f, 12.1f});
    pencils.push_back({1.6f, 24.6f});
    pencils.push_back({0.2f, 18.0f});
    vector<ListOfThings> myThings;
    myThings.push_back({ListOfThings::CatList, &cats});
    myThings.push_back({ListOfThings::PencilList, &pencils});
    
    cout << "Hey look, I just found the lists of the things I own. I made them a while ago. Let's take a look at them!\n\n";
    
    for (const ListOfThings& list : myThings) {
	if (list.type == ListOfThings::CatList) {
	    cout << "Ahh... A list of cats... curious...\n";
	    for (const Cat& cat : *static_cast<vector<Cat>*>(list.listData))
		cout << cat.name << ", age: " << cat.age << '\n';
	}
	else if (list.type == ListOfThings::PencilList) {
	    cout << "Hmm... A bunch of pencils...\n";
	    for (const Pencil& pencil : *static_cast<vector<Pencil>*>(list.listData)) {
		cout << "sharpness: " << pencil.sharpness << ", length: " << pencil.length << '\n';
	    }
	}
    }
}


In action: http://coliru.stacked-crooked.com/a/4b86064b808d2b91
There's no need for something like that.

The OP's problem is that s/he's trying to use vector<base>. This will cause any object being copied into it to be sliced, so that the objects stored in it are only of type base, not of their original type.

Instead, they should be using a vector<base*>, and storing pointers to the objects rather than sliced copies of the objects. Then, the overall list can be of type vector<vector<base*>>.
I make it like bellow but how i can access the real objects?

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <vector>

using namespace std;

struct base {};

vector<vector<base*> > all;

struct a1 : base
{
    int a;
    int b;
};
vector<base*>v1;
struct a2 : base
{
    int a;
    int b;
};
vector<base*>v2;

int main()
{
    a1 i;
    i.a=2;
    i.b=3;
    v1.push_back(&i);
    a1 j;
    j.a=2;
    j.b=3;
    v1.push_back(&j);

    a2 k;
    k.a=2;
    k.b=3;
    v2.push_back(&k);

    a2 l;
    l.a=2;
    l.b=3;
    v2.push_back(&l);


    all.push_back(v1);
    all.push_back(v2);

    for(vector<vector<base*> >::iterator it=all.begin(); it<all.end(); it++)
    {
        vector<base*> b=*it;
        for(vector<base*>::iterator it1=b.begin(); it1<b.end(); it1++)
        {

            base* a=*it1;
            int b=a->i;// problem, how can i have access to a1?
        }
    }

    return 0;
}
Last edited on
If a1 and a2 both have the same data members in common, why aren't those data members in the base class?

Edit: To answer your question in a more general sense: a pointer to the base class will only allow you to access:

a) members of the base class

b) members of the base class that are polymorphically overridden in subclasses

If you want to treat your pointer as if it were a pointer to a1, you need to cast it to one. I'd reccomend reading up on the different types of C++ casts.
Last edited on
No, a1 and a2 don't have same data, i write it wrong...
Unfortunately structs a1,a2, ... and vectors v1,v2,... are too many(>1000).
How i can cast all these stuff?
I am looking for a simple method to access all stuff.
Trying SneakySnake solution i have a problem with g++(mingw and codeblocks) at
for (const ListOfThings& list : myThings)

main.cpp|42|error: expected initializer before ':' token|

I thing is the new vercion of C++, the C++11?
I thing is the new vercion of C++, the C++11?

Yes.
If you are using Windows, I suggest you try Visual Studio 2013 Express, which has excellent C++11 support (both language and library).
@OP: You're trying to do X, and you thought of solution Y.
So you're asking about solution Y, without even mentioning X.
The problem is, there might be a better solution, but we can't know that unless you describe what X is.
solution X and Y resolve the same problem.
Different structs cary solution of different problems.
A matter has many solutions, that many same type of structs cary.
The matters are many=1000 and i have 2-3000 solutions in a 1000 vectors.

// two solutions of a matter 1 with struct a1 in vector v1
1
2
3
4
5
6
7
8
   a1 i;
    i.a=2;
    i.b=3;
    v1.push_back(&i);
    a1 j;
    j.a=4;
    j.b=5;
    v1.push_back(&j);


// two solutions of a matter 2 with struct a2 in vector v2

1
2
3
4
5
6
7
8
 a2 k;
    k.a=7;
    k.b=8;
    v2.push_back(&k);
    a2 l;
    l.a=9;
    l.b=10;
    v2.push_back(&l);


Now all that solutions v1 and v2 must deposit to all

1
2
 all.push_back(v1);
    all.push_back(v2);


and finally access all stuff.

The solve with SneakySneak solution works fine and many thanks.

There is a simpler way?





Last edited on
Also in code of SneakySnake some questions.
How i can externaly swap 2 elements of cats?


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct Cat
{
    string name;
    int age;
};

struct Pencil
{
    float sharpness;
    float length;
};

struct ListOfThings
{
    enum Type
    {
        CatList,
        PencilList
    } type;
    void *listData;
};

vector<Pencil> pencils;
vector<Cat> cats;
vector<ListOfThings> myThings;

void format(const ListOfThings::Type a)
{
swap(a[1],a[2]);// i have error
}

int main()
{
    cats.push_back( {"Joey", 4});
    cats.push_back( {"Mitzi", 6});
    cats.push_back( {"Garfield", 10});

    format(&cats); // error ...............

    pencils.push_back( {1.0f, 17.6f});
    pencils.push_back( {0.6f, 12.1f});
    pencils.push_back( {1.6f, 24.6f});
    pencils.push_back( {0.2f, 18.0f});

    myThings.push_back( {ListOfThings::CatList, &cats});
    myThings.push_back( {ListOfThings::PencilList, &pencils});

    cout << "Hey look, I just found the lists of the things I own. I made them a while ago. Let's take a look at them!\n\n";

    for (const ListOfThings& list : myThings)
    {
        if (list.type == ListOfThings::CatList)
        {
            cout << "Ahh... A list of cats... curious...\n";
            for (const Cat& cat : *static_cast<vector<Cat>*>(list.listData))
                cout << cat.name << ", age: " << cat.age << '\n';
        }
        else if (list.type == ListOfThings::PencilList)
        {
            cout << "Hmm... A bunch of pencils...\n";
            for (const Pencil& pencil : *static_cast<vector<Pencil>*>(list.listData))
            {
                cout << "sharpness: " << pencil.sharpness << ", length: " << pencil.length << '\n';
            }
        }
    }
}
Last edited on
Topic archived. No new replies allowed.