vector of structs compile error
Jan 8, 2017 at 5:59am UTC
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 Jan 8, 2017 at 5:59am UTC
Jan 8, 2017 at 6:07am UTC
vLayouts[0].vKeys[0].keyType = code1;
Jan 8, 2017 at 6:21am UTC
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;
}
Jan 8, 2017 at 7:20am UTC
vLayouts[0].vKeys[0].keyType = code1;
vKeys is an empty vector
Jan 8, 2017 at 7:25am UTC
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 Jan 8, 2017 at 10:06am UTC
Jan 8, 2017 at 7:46pm UTC
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 Jan 8, 2017 at 7:47pm UTC
Jan 8, 2017 at 10:10pm UTC
'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?
Jan 8, 2017 at 10:25pm UTC
kemort,
I appreciate the effort. I couldn't have done it without your help.
Jan 9, 2017 at 4:28am UTC
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 ;
}
}
Output1 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.