Use attribute from derived class while using method from the base class? - c++

I have the following code:
#include <map>
class vehicle {
private:
int id = 0;
std::map<std::pair<int, char>, int> seats{};
public:
void displaySeats();
};
class Bus : public vehicle {
private:
std::string type = "Bus";
public:
std::map<std::pair<int, char>, int> seats{ {{1,'A'},0 }, {{1,'B'},0 }, {{ 1,'C' }, 0}, {{ 1,'D' }, 0 }, {{ 1,'E' }, 0 },
{{2,'A'},0 }, {{2,'B'},0 }, {{ 2,'C' }, 0}, {{ 2,'D' }, 0 }, {{ 2,'E' }, 0 },
{{3,'A'},0 }, {{3,'B'},0 }, {{ 3,'C' }, 0}, {{ 3,'D' }, 0 }, {{ 3,'E' }, 0 },
{{4,'A'},0 }, {{4,'B'},0 }, {{ 4,'C' }, 0}, {{ 4,'D' }, 0 }, {{ 4,'E' }, 0 },
{{5,'A'},0 }, {{5,'B'},0 }, {{ 5,'C' }, 0}, {{ 5,'D' }, 0 }, {{ 5,'E' }, 0 }};
};
class MiniVan : public vehicle {
private:
std::string type = "MiniVan";
public:
// Seats map. <int, char> represents seats id(1A 1B 1C) the <int> will be either 0 or 1, representing if the seat is taken(1) or free(0).
std::map<std::pair<int, char>, int> seats{ {{1,'A'},0 }, {{1,'B'},0 }, {{ 1,'C' }, 0},
{{2,'A'},0 }, {{2,'B'},0 }, {{ 2,'C' }, 0},
{{3,'A'},0 }, {{3,'B'},0 }, {{ 3,'C' }, 0},
{{4,'A'},0 }, {{4,'B'},0 }, {{ 4,'C' }, 0} };
};
void vehicle::displaySeats()
{
std::pair<int, char> seat{ 1, 'E'};
int columns = 5?this->seats.count(seat)>0:3;
int displayRow = 0;
for (const auto& p : this->seats) {
if (displayRow == columns) {
std::cout << std::endl;
displayRow = 0;
}
displayRow++;
std::cout << p.first.first << p.first.second << "\t ";
}
};
In main() i have:
MiniVan testMiniVan;
testMiniVan.displaySeats();
It displays the empty seats map attribute from the base class.
I am new to c++, but in other languages, it takes the derived class attribute. How can I solve this problem? Will I have to create displaySeats for each child class ? If yes, then why do I need base class in the first place?

This is something I've done fairly often as well, the issue is how things are constructed and which functions have access to which variables. Maybe you could do something like:
class Vehicle {
private:
int id = 0;
std::map<std::pair<int, char>, int> seats{};
public:
// Add a constructor that takes in the `seats` map
Vehicle(std::map<std::pair<int, char>, int> s) : seats(std::move(s)) {}
void displaySeats();
};
and then for each child class:
class MiniVan : public Vehicle {
private:
std::string type = "MiniVan";
public:
// call the parent constructor passing in the seat map
MiniVan() : Vehicle({{1,'A'},0 }, ...}) {}
};
Another approach would be to make a virtual function on the base class like:
class Vehicle {
...
protected:
...
const std::map<std::pair<int, char>, int>& get_seats() const = 0;
};
that the displaySeats function would call instead of directly loading this->seats. Each child class would need to define get_seats(), but that would be pretty easy (pretty much just return seats;). Hopefully that makes sense, let me know if not!

Related

C++ Boost graph libary Add_vertex with custom properties and check for redundancy

I want to create a boost graph from a GeoJSON file containg a network of linestrings. Some linestrings have common nodes. In other words: everything is somehow connected.
the file looks like this: (here only 3 linestrings: in reality more than 8000).
{"type": "Feature", "properties": {"id": 1}, "geometry": { "type": "LineString", "coordinates": [ [ 147.0, -4.8 ], [ 141.0, -2.0 ] ]}},
{"type": "Feature", "properties": {"id": 2}, "geometry": { "type": "LineString", "coordinates": [ [ 152.6, -5.2 ], [ 152.05, -3.8 ], [ 147.0, -4.8 ] ] } },
{"type": "Feature", "properties": {"id": 3}, "geometry": { "type": "LineString", "coordinates": [ [ 147.0, -4.8 ], [ 144.73, 0.0 ] ] } },
You see that the coordinate [147.0, -4.8] is part of all 3 linestrings.
I iterate over this file and save these information in a vector linestrings containing struct variables called linestring:
struct linestring //data of one linestring
{
int id;
std::vector<std::vector<double>> pos; //2D vector conatining x and y positions
};
std::vector <linestring> linestrings; //containing the inforamtion of all linestrings
Now I want to use this to build a boost graph:
struct Nodes
{
double x;
double y;
};
struct Legs
{
int id;
double distance;
//edge weight calculated with distance=sqrt((x2-x1)^2+(y2-y1)^2) euclidean distance
};
typedef adjacency_list<listS, vecS, undirectedS, Nodes, Legs> graph_t;
graph_t LinestringGraph;
Which commands are recommended for such a job?
I don't want to add all vertexes and check for redundancy by iterating or other time consuming stuff.
Is there a possibility to add an edge with the custom id and the calculated edge weight together with the vertexes containing the custom property of xy-coordinate.
I want to do something like this:
PSEUDOCODE:
iterate over the vector linestrings
count the number of waypoints in the linestring
//e.g. in id=2 are "coordinates":
// [ [ 152.6, -5.2 ], [ 152.05, -3.8 ], [ 147.0, -4.8 ] ]
//edge from [ 152.6, -5.2 ] to [ 152.05, -3.8 ]
// and from [ 152.05, -3.8 ] to [ 147.0, -4.8 ]
add counted edges to the boost graph
and weight with euclidean distance of start and end coordinate of
the current (part)linestring.
if one vertex already exists (e.g. [ 147.0, -4.8 ])
do not create a new vertex --> use the existing
######################################
AFTER the very helpful answer of #sehe and #ravenspoint (Thank you for the very quick reply. I never expect such help) I tried this:
#include <iostream>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
using namespace boost;
struct point // single point/node
{
double lon, lat; //not yet x, y because I want to use longitude and latitude
auto operator==(const point &other)
{
return abs(this->lon - other.lon)< 0.000000000001
&& abs(this->lat - other.lat < 0.000000000001;
}
//thanks for the operator hint from #sehe
};
struct Legs
{
int id;
double Distance; // edge weight
};
struct linestring // data of single linestring
{
int id;
std::vector<point> coords; // vector with double lon/lat
};
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
point, Legs>;
using V = G::vertex_descriptor;
using E = G::edge_descriptor;
int main()
{
std::vector<linestring> linestrings; // vector with all linestrings
//some not relevant code for this question: reading in the JSON file with poco
//everything is now stored in the vector linestrings
//you can acess it in the following way:
for (linestring i : linestrings)
{
std::cout << std::endl;
std::cout << "id: " << i.id << std::endl;
std::cout << "Number of waypoints: "
<< i.coords.size() << " \nwaypoints are: (lon, lat): ";
for (point waypoint : i.coords)
{
std::cout << std::endl;
std::cout << "(" << waypoint.lon << ", " << waypoint.lat << ")";
}
std::cout << std::endl;
}
std::map<point, V> mapping;
for (auto &f : linestrings)
{
for (auto &p : f.coords)
{
std::cout << std::endl;
std::cout << p.lon << ", " << p.lat << std::endl;
if (auto it = mapping.find(p); it == mapping.end())
{
mapping.emplace(p, add_vertex(p, g));
}
}
};
return 0;
}
With this I get the error:
error C2678: binary '<': no operator found which takes a left-hand operand of type 'const _Ty' (or there is no acceptable conversion)
I tried instead of operator== the operator< but still same result/error
after the line from #sehe
int next_edge_id = 0;
I don't understand how to proceed and add the edges to the graph according to a linestring in the linestrings vector.
To make #ravenspoint's suggestion concrete, I'd flip it around a bit:
LOOP over waypoints, creating vertices for each unseen coordinate, storing a mapping point→vertex_descriptor.
LOOP over linestrings, looking up the previously mapped vertices
Live On Coliru
#include <boost/json/src.hpp>
#include <iostream>
namespace json = boost::json;
using json::value_from;
using coord = double;
struct point {
coord x, y;
auto operator<=>(point const&) const = default;
friend std::ostream& operator<<(std::ostream& os, point const& p) {
return os << "(" << p.x << "," << p.y << ")";
}
friend void tag_invoke(json::value_from_tag, json::value& jv, point const& p) {
jv = {value_from(p.x), value_from(p.y)};
}
friend point tag_invoke(json::value_to_tag<point>, json::value const& jv) {
auto& arr = jv.as_array();
return {arr[0].as_double(), arr[1].as_double()};
}
};
using linestring = std::vector<point>;
struct feature {
intmax_t id;
linestring geom;
friend void tag_invoke(json::value_from_tag, json::value& jv, feature const& f) {
jv = {{"type", "Feature"},
{"properties", {"id", f.id}},
{
"geometry",
{
{"type", "LineString"},
{"coordinates", value_from(f.geom)},
},
}};
}
friend feature tag_invoke(json::value_to_tag<feature>, json::value const& jv) {
assert(jv.at("type") == "Feature");
auto& props = jv.at("properties").as_object();
auto& geom = jv.at("geometry").as_object();
assert(geom.at("type") == "LineString");
return {
props.at("id").as_int64(),
json::value_to<linestring>(geom.at("coordinates")),
};
}
};
using features = std::vector<feature>;
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
struct Legs {
int id;
double distance;
};
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
point, Legs>;
using V = G::vertex_descriptor;
using E = G::edge_descriptor;
int main() {
auto ff = value_to<features>(json::parse(R"([
{"type": "Feature", "properties": {"id": 1}, "geometry": { "type": "LineString", "coordinates": [ [ 147.0, -4.8 ], [ 141.0, -2.0 ] ]}},
{"type": "Feature", "properties": {"id": 2}, "geometry": { "type": "LineString", "coordinates": [ [ 152.6, -5.2 ], [ 152.05, -3.8 ], [ 147.0, -4.8 ] ] } },
{"type": "Feature", "properties": {"id": 3}, "geometry": { "type": "LineString", "coordinates": [ [ 147.0, -4.8 ], [ 144.73, 0.0 ] ] } }
])"));
G g;
std::map<point, V> mapping;
// create a mapping for all vertices
for (auto& f : ff)
for (auto& p : f.geom)
if (auto it = mapping.find(p); it == mapping.end())
mapping.emplace(p, add_vertex(p, g));
int next_edge_id = 0;
for (auto& f : ff) {
auto waypoints = boost::make_iterator_range(f.geom);
if (waypoints.empty())
continue;
V s = mapping.at(waypoints.front()), t;
for (; waypoints.pop_front(), !waypoints.empty(); s = t) {
t = mapping.at(waypoints.front());
auto dx = g[t].x- g[s].x;
auto dy = g[t].y- g[s].y;
add_edge(s, t, Legs{next_edge_id++, sqrt(dx * dx + dy * dy)}, g);
}
}
print_graph(g, get(boost::vertex_bundle, g));
}
Prints
(147,-4.8) <--> (141,-2) (152.05,-3.8) (144.73,0)
(141,-2) <--> (147,-4.8)
(152.6,-5.2) <--> (152.05,-3.8)
(152.05,-3.8) <--> (152.6,-5.2) (147,-4.8)
(144.73,0) <--> (147,-4.8)
CAVEAT
Keep in mind floating point inexactness. You might want to implement operator< differently for point so that Very Close Points(TM) may be treated as identical.
I don't want to add all vertexes and check for redundancy by iterating
or other time consuming stuff.
Iterating is how computers accomplish stuff. The STL containers help you do it fast and efficiently, with very few lines of code. Like this:
void cVertex::indexer(std::vector<cVertex>& vertexVector)
{
auto it = std::find(
vertexVector.begin(),
vertexVector.end(),
*this);
if (it == vertexVector.end())
{
// new unique vertex
myIndex = vertexVector.size();
vertexVector.push_back(*this);
}
else
{
// duplicate vertex
myIndex = it->myIndex;
}
}
void cSolution::indexUniqueVertices()
{
std::vector<cVertex> vertexVector;
// loop over all line strings
for (auto &l : myLineString)
{
// loop over edges in line string
for (auto &e : l.myEdge)
{
// index the vertices
e.v1.indexer(vertexVector);
e.v2.indexer(vertexVector);
}
}
Output is
unique vertices
0 (147 -4.8)
1 (141 -2)
2 (152.6 -5.2)
3 (152.05 -3.8)
4 (144.73 0)
{"type": "Feature", "properties": {"id": 1}, "geometry": { "type": "LineString",
"coordinates": [ [ 147.0, -4.8 ], [ 141.0, -2.0 ] ]}}
has edges:
0 (147 -4.8) to 1 (141 -2)
{"type": "Feature", "properties": {"id": 2}, "geometry": { "type": "LineString",
"coordinates": [ [ 152.6, -5.2 ], [ 152.05, -3.8 ], [ 147.0, -4.8 ] ] } }
has edges:
2 (152.6 -5.2) to 3 (152.05 -3.8)
3 (152.05 -3.8) to 0 (147 -4.8)
{"type": "Feature", "properties": {"id": 3}, "geometry": { "type": "LineString",
"coordinates": [ [ 147.0, -4.8 ], [ 144.73, 0.0 ] ] } }
has edges:
0 (147 -4.8) to 4 (144.73 0)
Code for the complete application at https://github.com/JamesBremner/GeoJSONtoGraph/blob/main/src/main.cpp
PERFORMANCE
This code can handle 10,000 vertices in 0.1 second.
Most of the time is spent searching through the vector checking for a redundant node. Here is the detailed timing profile
Calls Mean (secs) Total Scope
1 0.098734 0.098734 vector
20008 4.79804e-06 0.0959992 vector find
I thought that using a set, which uses a binary search, might be faster at the cost of some extra code complexity.
Calls Mean (secs) Total Scope
1 3.19261 3.19261 set
20008 0.00015777 3.15666 set find
Surprising!

Initialize the array of struct in c++11

I am facing a problem in initializing an array of struct. Below is the code:
#include <iostream>
#include <array>
#include <string>
#define NUM_ELEMENT 5
struct Person
{
std::string m_name;
int m_age = 0;
Person() = default;
Person(std::string name, int age)
: m_name(name), m_age(age) {}
};
typedef std::array<Person, NUM_ELEMENT> PersonList;
class Detail
{
public:
void InitializePerson();
private:
PersonList personList;
};
void Detail::InitializePerson()
{
personList{ // <------ Getting Error here..
Person("abc", 10),
Person("cde", 20),
Person("pqr", 30),
Person("xyz", 40),
Person("apple", 50),
};
}
int main()
{
Detail detail;
detail.InitializePerson();
return 0;
}
Though, I know I can use the std::vector with push_back but I want to achive this through the static array as it elements are fixed. I want to initialize the array with above class Detail member and since the data can be random, so not able to do in for loop by personList[0] = Person{};
You are trying to initialize personList which can only be done at construction - but personList is already constructed so that doesn't work. You should be assigning instead:
personList = {
Person("abc", 10),
Person("cde", 20),
Person("pqr", 30),
Person("xyz", 40),
Person("apple", 50),
};
alternatively:
personList = {{
{"abc", 10},
{"cde", 20},
{"pqr", 30},
{"xyz", 40},
{"apple", 50},
}};
If you want it initialized, you could do that in a Detail constructor:
class Detail {
public:
Detail() :
personList{{
{"abc", 10},
{"cde", 20},
{"pqr", 30},
{"xyz", 40},
{"apple", 50},
}}
{}
private:
PersonList personList;
};
Seems you are missing = operator
personList = {
Person("abc", 10),
Person("cde", 20),
Person("pqr", 30),
Person("xyz", 40),
Person("apple", 50),
};
This seems to do
personList = {{
{ "abc", 10 },
{ "cde", 20 },
{ "pqr", 30 },
{ "xyz", 40 },
{ "apple", 50 },
}};
See this answer.

How to delete nested json data using nlohmann c++

I have a below json data. I am using nlohmann json in C++.
{
"CompanyName": "XYZ Tech",
"Created": "2019-10-16T20:14:29Z",
"TxnId": "4509237",
"Tags": [
{
"ROIId": "Default",
"Time": 71,
"Tracker": "emp10"
},
{
"ROIId": "MC16",
"Time": 21,
"TrackerId": "emp10"
},
{
"ROIId": "Default",
"Time": 11,
"TrackerId": "emp11"
},
{
"ROIId": "MC18",
"Time": 10,
"TrackerId": "emp11"
}
],
"Type": "TxnData"
}
In above json data, inside Tags, we have data where the ROIId is Default. I want to delete it so that the data becomes:
{
"CompanyName": "XYZ Tech",
"Created": "2019-10-16T20:14:29Z",
"TxnId": "4509237",
"Tags": [
{
"ROIId": "MC16",
"Time": 21,
"TrackerId": "emp10"
},
{
"ROIId": "MC18",
"Time": 10,
"TrackerId": "emp11"
}
],
"Type": "TxnData"
}
How can I do it in c++. Thanks
I suggest iterating through the json::array stored in Tags and saving the Key of the matched elements. This way you can later validate the deletion and safely delete the elements.
Note that deleting is exactly like erasing with a STL vector - I prefer to delete from the end of the vector to avoid changing the keys while deleting multiple elements.
Here is a quick and dirty demo
And here is the code:
#include <iostream>
#include <vector>
#include "json3.6.1.hpp"
unsigned removeDefaultROIID(nlohmann::json& jsonObject, const std::string& value) {
std::vector<int> toremove;
//Loop through the `tags` json::array and create a vector of indexes to delete:
for (auto &it : jsonObject["Tags"].items()) {
//`.get<std::string>()` is the best way to make sure we are getting the value as std::string
if (it.value().at("ROIId").get<std::string>() == value)
toremove.push_back(stoi(it.key()));
}
//sort it before erase - we want to delete first biggest index:
std::sort(toremove.rbegin(), toremove.rend());
//delete using `.erase()` method:
for (int &it : toremove)
jsonObject["Tags"].erase(jsonObject["Tags"].begin() + it);
return toremove.size();
}
int main()
{
//Create the JSON object:
nlohmann::json jsonObject = R"({"CompanyName":"XYZ Tech","Created":"2019-10-16T20:14:29Z","TxnId":"4509237","Tags":[{"ROIId": "Default","Time": 71,"Tracker": "emp10"},{"ROIId":"MC16","Time": 21,"TrackerId": "emp10"},{"ROIId":"Default","Time":11,"TrackerId":"emp11"},{"ROIId":"MC18","Time": 10,"TrackerId":"emp11"}],"Type":"TxnData"})"_json;
std::cout << "JSON nested object value conditional erase:" << std::endl;
std::cout << "JSON object TAGS count - BEFORE deletion:" << jsonObject["Tags"].size() << std::endl;
//Call the method -> jlson is passed by ref
unsigned removed = removeDefaultROIID(jsonObject, "Default");
std::cout << "JSON object TAGS count - AFTER deletion:" << jsonObject["Tags"].size() << std::endl;
return 0;
}

Large static arrays in header only implementation

Due to the need to be able to reference unicode character groups in a header only implementation, I want to declare all the arrays first. Templates allow me to initialize static members in the header, but the code looks messy.
This is just two of the twenty or so groups:
struct CharacterClass
{
struct Value
{
int l;
int h;
};
};
template < int N >
struct Nd : public CharacterClass
{
static const Value v[];
};
template< int N >
const typename Nd< N >::Value Nd< N >::v[] = {
{ 0x00030 , 0x00039 }, { 0x00660 , 0x00669 }, { 0x006f0 , 0x006f9 }, { 0x007c0 , 0x007c9 }, { 0x00966 , 0x0096f },
{ 0x009e6 , 0x009ef }, { 0x00a66 , 0x00a6f }, { 0x00ae6 , 0x00aef }, { 0x00b66 , 0x00b6f }, { 0x00be6 , 0x00bef },
{ 0x00c66 , 0x00c6f }, { 0x00ce6 , 0x00cef }, { 0x00d66 , 0x00d6f }, { 0x00e50 , 0x00e59 }, { 0x00ed0 , 0x00ed9 },
{ 0x00f20 , 0x00f29 }, { 0x01040 , 0x01049 }, { 0x017e0 , 0x017e9 }, { 0x01810 , 0x01819 }, { 0x01946 , 0x0194f },
{ 0x019d0 , 0x019d9 }, { 0x01b50 , 0x01b59 }, { 0x0ff10 , 0x0ff19 }
};
template < int N >
struct Nl : public CharacterClass
{
static const Value v[];
};
template< int N >
const typename Nl< N >::Value Nl< N >::v[] = {
{ 0x016ee , 0x016f0 }, { 0x02160 , 0x02182 }, { 0x03007, 0x03007 }, { 0x03021 , 0x03029}, { 0x03038 , 0x0303a }
};
Q1: Is it possible to declare the array once in a base class without having to repeat it for each derived type?
Q2: How can I hide the dummy 'int N', so that I can later reference the structs without having to add the template parameter? ie. int x = Nd.v[10].l;
Q3: Is there a better way of doing this?
I will try to give you an alternative for Q1 you've asked.
I don't like to see hard-coded values which are meaningless to the program logics.
Here's a nice trick That I use sometimes:
Create a new file and paste the values in it.
data.dat
{ 0x00030 , 0x00039 }, { 0x00660 , 0x00669 }, { 0x006f0 , 0x006f9 }, { 0x007c0 , 0x007c9 }, { 0x00966 , 0x0096f },
{ 0x009e6 , 0x009ef }, { 0x00a66 , 0x00a6f }, { 0x00ae6 , 0x00aef }, { 0x00b66 , 0x00b6f }, { 0x00be6 , 0x00bef },
{ 0x00c66 , 0x00c6f }, { 0x00ce6 , 0x00cef }, { 0x00d66 , 0x00d6f }, { 0x00e50 , 0x00e59 }, { 0x00ed0 , 0x00ed9 },
{ 0x00f20 , 0x00f29 }, { 0x01040 , 0x01049 }, { 0x017e0 , 0x017e9 }, { 0x01810 , 0x01819 }, { 0x01946 , 0x0194f },
{ 0x019d0 , 0x019d9 }, { 0x01b50 , 0x01b59 }, { 0x0ff10 , 0x0ff19 }
now, when you want to repeat it, do the following:
const typename Nd< N >::Value Nd< N >::v[] = {
#include "data.dat"
};
This way, the preprocessor will paste all this values for you, so you don't need to repeat them all the time.
Answering my own questions. I placed the whole combined array in a base class, then derived from that with derived types initializing themselves to an index within the array.
struct CharacterClass
{
struct Value
{
int l;
int h;
};
};
template < int X >
struct Base : public CharacterClass
{
static const Value v[];
};
template< int X >
const typename Base< X >::Value Base< X >::v[] = {
// Nd values length 23 index 0
{ 0x00030 , 0x00039 }, { 0x00660 , 0x00669 }, { 0x006f0 , 0x006f9 }, { 0x007c0 , 0x007c9 }, { 0x00966 , 0x0096f },
{ 0x009e6 , 0x009ef }, { 0x00a66 , 0x00a6f }, { 0x00ae6 , 0x00aef }, { 0x00b66 , 0x00b6f }, { 0x00be6 , 0x00bef },
{ 0x00c66 , 0x00c6f }, { 0x00ce6 , 0x00cef }, { 0x00d66 , 0x00d6f }, { 0x00e50 , 0x00e59 }, { 0x00ed0 , 0x00ed9 },
{ 0x00f20 , 0x00f29 }, { 0x01040 , 0x01049 }, { 0x017e0 , 0x017e9 }, { 0x01810 , 0x01819 }, { 0x01946 , 0x0194f },
{ 0x019d0 , 0x019d9 }, { 0x01b50 , 0x01b59 }, { 0x0ff10 , 0x0ff19 },
// Nl values length 5 index 23
{ 0x016ee , 0x016f0 }, { 0x02160 , 0x02182 }, { 0x03007, 0x03007 }, { 0x03021 , 0x03029}, { 0x03038 , 0x0303a }
};
template < int _index, int _length >
struct BaseIndex : public Base< 0 >
{
static const Value * v;
static const int length;
};
template < int _index, int _length >
const typename BaseIndex< _index, _length >::Value * BaseIndex< _index, _length >::v = &Base::v[ _index ];
template < int _index, int _length >
const int BaseIndex< _index, _length >::length = _length;
struct Nd : public BaseIndex< 0, 23 >
{
};
struct Nl : public BaseIndex< 23, 5 >
{
};
I think just a typedef in the namespace can replace those struct's Nd and Nl.
If there's a better way, I'm still open to suggestions.

Problems accessing pre-defined array of floats in C++

I'm trying to make use of precalculated values by outputting them to a header file and then compiling them for use.
The precalculated values are cube co ordinates mapped onto a sphere and the data structure takes the form of:
typedef float heightMapCubeFace[5][5][3];
I am defining each face seperately like so:
heightMapCubeFace face1 = {{{ -2.88675, -2.88675, -2.88675 }, { -3.38502, -3.38502, -1.44338 }, { -3.53553, -3.53553, 0 }, { -3.38502, -3.38502, 1.44338 }, { -2.88675, -2.88675, 2.88675}},
{{ -1.44338, -3.38502, -3.38502 }, { -1.69251, -4.38986, -1.69251 }, { -1.76777, -4.67707, 0 }, { -1.69251, -4.38986, 1.69251 }, { -1.44338, -3.38502, 3.38502}},
{{ 0, -3.53553, -3.53553 }, { 0, -4.67707, -1.76777 }, { 0, -5, 0 }, { 0, -4.67707, 1.76777 }, { 0, -3.53553, 3.53553}},
{{ 1.44338, -3.38502, -3.38502 }, { 1.69251, -4.38986, -1.69251 }, { 1.76777, -4.67707, 0 }, { 1.69251, -4.38986, 1.69251 }, { 1.44338, -3.38502, 3.38502}},
{{ 2.88675, -2.88675, -2.88675 }, { 3.38502, -3.38502, -1.44338 }, { 3.53553, -3.53553, 0 }, { 3.38502, -3.38502, 1.44338 }, { 2.88675, -2.88675, 2.88675}}
};
and finally:
heightMapCubeFace * heightMapSaved[6] = {&face1, &face2, &face3, &face4, &face5, &face6};
Eventually the data structue will be bigger I hav ejust set it to 5x5 to make things easier at first.
The problem I am having is when I want to get the values back, something weird is happening and as a result access violations are occuring.
As shown in the following image
As you can see the assigned value does not match that of the data structure. Instead the value for index [0][0][0][1] is given the value of index [0][0][1][0].
here
I picked up on this because an unhaddled exception is thrown at a later stage (access violation), I think it is because of this index problem but can't be certain.
I don't understand what is going on, am I dereferencing the pointer wrong?
Any help would be much appriciated, thanks.
Here is the code for that section:
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < heightMapRes; j++)
{
for(int k = 0; k < heightMapRes; k++)
{
float xCoord = *(heightMapSaved[i][j][k][0]);
float yCoord = *(heightMapSaved[i][j][k][1]);
float zCoord = *(heightMapSaved[i][j][k][2]);
float newValue = myModule.GetValue( xCoord, yCoord, zCoord);
heightMap.SetValue( j, k, newValue);
}
}
}
layout is (heightMapSaved[6])[5][5][3] not (heightMapSaved[5][5][3][6])