vector of structs compile error

The following code gets this compile error:

1
2
vector_structs.cpp:23:17: error: ‘__gnu_cxx::__alloc_traits<std::allocator<main()::Layout> >::value_type {aka struct main()::Layout}’ has no member named ‘keyType’
     vLayouts[0].keyType = code1;


Why is there no member named ‘keyType’? It's right there in struct Key!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <vector>
#include <iostream>

int main()
{
    struct Key
    {
        std::string keyType;
        std::vector<std::string> codes;     //empty vector
    };

    struct Layout
    {
        std::vector<Key> vKeys;             //empty vector
    };

    std::vector<Layout> vLayouts;

    Layout layout1;
    vLayouts.push_back(layout1);

    std::string code1="1";
    vLayouts[0].keyType = code1; //error: has no member named ‘keyType’
}


Thank you.
Last edited on
vLayouts[0].vKeys[0].keyType = code1;
Thanks gunnerfunner. Line 23 compiles now. But when it runs, line 23 gets seg fault:
1
2
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b74ac1 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /lib64/libstdc++.so.6


Here is the updated code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <vector>
#include <iostream>

int main()
{
    struct Key
    {
        std::string keyType;
        std::vector<std::string> codes;     //empty vector
    };

    struct Layout
    {
        std::vector<Key> vKeys;             //empty vector
    };

    std::vector<Layout> vLayouts;

    Layout layout1;
    vLayouts.push_back(layout1);

    std::string code1="1";
    vLayouts[0].vKeys[0].keyType = code1;
}
vLayouts[0].vKeys[0].keyType = code1;

vKeys is an empty vector
closed account (48T7M4Gy)
An attempt at untangling somewhat bizarre data structures and variable names. Also consistent with Thomas's comment on otherwise empty vectors.

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

int main()
{
    struct Key
    {
        std::string keyType;
        std::vector<std::string> codes;     //empty vector of codes
    };
    
    struct Layout
    {
        std::vector<Key> vKeys;             //empty vector of keys
    };
    
    std::vector<Layout> vLayouts;
    
    Layout layout1;
    vLayouts.push_back(layout1);
    
    std::string key="1";
    std::string code1 = "code corresponding to 1";
    std::string code2 = "another code corresponding to 1";
    
    Key k;
    k.keyType = key;
    k.codes.push_back(code1);
    k.codes.push_back(code2);
    
    layout1.vKeys.push_back(k);
    
    std::cout << k.keyType << '\n';
    
    Key temp = layout1.vKeys[0];
    
    std::cout << temp.keyType << ' ' << temp.codes[0]<< '\n';
    std::cout << temp.keyType << ' ' << temp.codes[1]<< '\n';
    
    return 0;
}
1
1 code corresponding to 1
1 another code corresponding to 1
Program ended with exit code: 0
Last edited on
Thank you kemort.

From your example, I was able to write what I needed.
Sorry about the bizarre data structures and variable names.
I updated the variable names to something more sensible.
What is bizarre about the data structures?

The following does what I want it to do, but I get the feeling there is an easier way.

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
74
75
76
77
78
#include <vector>
#include <string>
#include <iostream>

int main()
{
    //define structs and vectors
    struct Key
    {
        std::string keyType;
        std::vector<std::string> vCodes;
    };

    struct Row
    {
        std::vector<Key> vKeys;
    };

    struct Layout
    {
        std::vector<Row> vRows;
    };

    std::vector<Layout> vLayouts;

    //instantiate structs and vectors
    for (unsigned int layout = 0; layout < 2; layout++)
    {
        Layout layout0;
        vLayouts.push_back(layout0);

        for (unsigned int row = 0; row < 2; row++)
        {
            Row row00;
            vLayouts[layout].vRows.push_back(row00);

            for (unsigned int key = 0; key < 2; key++)
            {
                std::string keyType00 = "type" + std::to_string(layout)
                    + std::to_string(row) + std::to_string(key);
                Key key00;
                vLayouts[layout].vRows[row].vKeys.push_back(key00);
                vLayouts[layout].vRows[row].vKeys[key].keyType = keyType00;

                for (unsigned int code = 0; code < 2; code++)
                {
                    std::string code000 = "code" + std::to_string(layout)
                        + std::to_string(row) + std::to_string(key) + std::to_string(code);
                    vLayouts[layout].vRows[row].vKeys[key].vCodes.push_back(code000);
                }
            }
        }
    }

    //print vectors
    for (unsigned int layout = 0; layout < vLayouts.size(); layout++)
    {
        std::cout << "layout=" << layout << "\n";

        for (unsigned int row = 0; row < vLayouts[layout].vRows.size(); row++)
        {
            std::cout << "  row=" << layout << row << "\n";

            for (unsigned int key = 0; key < vLayouts[layout].vRows[row].vKeys.size(); key++)
            {
                std::cout << "    " << vLayouts[layout].vRows[row].vKeys[key].keyType << "\n";

                for (unsigned int code = 0;
                        code < vLayouts[layout].vRows[row].vKeys[key].vCodes.size(); code++)
                {
                    std::cout << "      "
                        << vLayouts[layout].vRows[row].vKeys[key].vCodes[code] << "\n";
                }
            }
        }
    }
    return 0;
}

output:
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
layout=0
  row=00
    type000
      code0000
      code0001
    type001
      code0010
      code0011
  row=01
    type010
      code0100
      code0101
    type011
      code0110
      code0111
layout=1
  row=10
    type100
      code1000
      code1001
    type101
      code1010
      code1011
  row=11
    type110
      code1100
      code1101
    type111
      code1110
      code1111
Last edited on
closed account (48T7M4Gy)
'Bizarre' didn't mean it is no good. It described the abstract vs intuitively obvious nature and context of the structs. Without that context it's difficult to comment on whether there is a better way except the <multiset>'s might be a possibility?
kemort,

I appreciate the effort. I couldn't have done it without your help.
Overloading ctors, subscript and insertion operators could be another way of doing this:
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <iostream>
#include <vector>

constexpr auto vSIZE = 2;

struct Key
{
    std::string keyType = std::string("key");
    std::vector<std::string> vCodes;     //empty vector
    Key (const std::string& tmp_keyType, const std::vector<std::string>& tmp_vCodes)
    : keyType(tmp_keyType), vCodes(tmp_vCodes) {}
    Key(const std::vector<std::string>& tmp_vCodes) : vCodes(tmp_vCodes){}
    std::string& operator [](const size_t i)
    {
        if (i > vCodes.size() || i < 0)
        {
            std::cout << "Index out of bounds \n";
            return vCodes[0];
        }
        else
        {
            return vCodes[i];
        }
    }
    const std::string& operator [](const size_t i)const
    {
        if (i > vCodes.size() || i < 0)
        {
            std::cout << "Index out of bounds \n";
            return vCodes[0];
        }
        else
        {
            return vCodes[i];
        }
    }
};
std::ostream& operator << (std::ostream& os, const Key& k)
{
    os << k.keyType << '\n';
    for (auto& elem : k.vCodes)
    {
        os << elem << " ";
    }
    return os;
}
struct Row
{
    std::vector<Key> vKeys;
    Row (const std::vector<Key>& tmp_vKeys) : vKeys(tmp_vKeys) {}
    Key& operator [](const size_t i)
    {
        if (i > vKeys.size() || i < 0)
        {
            std::cout << "Index out of bounds \n";
            return vKeys[0];
        }
        else
        {
            return vKeys[i];
        }
    }
    const Key& operator [](const size_t i)const
    {
        if (i > vKeys.size() || i < 0)
        {
            std::cout << "Index out of bounds \n";
            return vKeys[0];
        }
        else
        {
            return vKeys[i];
        }
    }
};
std::ostream& operator << (std::ostream& os, const Row& r)
{
    for (auto& elem : r.vKeys)
    {
        os << elem << '\n';
    }
    return os;
}
struct Layout
{
    std::vector<Row> vRows;             //empty vector
    Layout (const std::vector<Row>& tmp_vRows) : vRows(tmp_vRows) {}
    Row& operator [](const size_t i)
    {
        if (i > vRows.size() || i < 0)
        {
            std::cout << "Index out of bounds \n";
            return vRows[0];
        }
        else
        {
            return vRows[i];
        }
    }
    const Row& operator [](const size_t i)const
    {
        if (i > vRows.size() || i < 0)
        {
            std::cout << "Index out of bounds \n";
            return vRows[0];
        }
        else
        {
            return vRows[i];
        }
    }
};
std::ostream& operator << (std::ostream& os, const Layout& l)
{
    for (auto& elem : l.vRows)
    {
        os << elem << '\n';
    }
    return os;
}
int main()
{
    std::string tmp_string = " ";
    std::vector <std::string> tmp_Codes;
    for (size_t i = 0; i < vSIZE; i++)
    {
        tmp_Codes.push_back(tmp_string);
    }

    Key tmp_key1(std::string("first_key"), tmp_Codes), tmp_key2(std::string("second_key"), tmp_Codes);
    std::vector<Key> tmp_vKeys;

    tmp_vKeys.push_back(tmp_key1);
    tmp_vKeys.push_back(tmp_key2);

    Row tmp_row(tmp_vKeys);
    std::vector<Row> tmp_vRows;
    for (size_t i = 0; i < vSIZE; i++)
    {
        tmp_vRows.push_back(tmp_row);
    }

    Layout tmp_Layout(tmp_vRows);
    std::vector <Layout> vLayouts;

    for (size_t i = 0; i < vSIZE; i++)
    {
        vLayouts.push_back(tmp_Layout);
    }
    vLayouts [0][0][0][0] = std::string ("a");
    vLayouts [0][0][0][1] = std::string ("b");
    vLayouts [0][0][1][0] = std::string ("c");
    vLayouts [0][0][1][1] = std::string ("d");
    vLayouts [0][1][0][0] = std::string ("e");
    vLayouts [0][1][0][1] = std::string ("f");
    vLayouts [0][1][1][0] = std::string ("g");
    vLayouts [0][1][1][1] = std::string ("h");

    vLayouts [1][0][0][0] = std::string ("i");
    vLayouts [1][0][0][1] = std::string ("j");
    vLayouts [1][0][1][0] = std::string ("k");
    vLayouts [1][0][1][1] = std::string ("l");
    vLayouts [1][1][0][0] = std::string ("m");
    vLayouts [1][1][0][1] = std::string ("n");
    vLayouts [1][1][1][0] = std::string ("o");
    vLayouts [1][1][1][1] = std::string ("p");

    for (auto& elem : vLayouts)
    {
        std::cout << elem ;
    }
}

Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
first_key
a b
second_key
c d

first_key
e f
second_key
g h

first_key
i j
second_key
k l

first_key
m n
second_key
o p


Process returned 0 (0x0)   execution time : 0.096 s
Press any key to continue.

Topic archived. No new replies allowed.