I'm working on converting a lua program into a C++ program but I've hit a road block, I can't figure out how to convert this into C++
function newPool()
local pool = {}
pool.species = {} --imports data from local species = {}
pool.generation = 0
pool.innovation = Outputs
pool.currentSpecies = 1
pool.currentGenome = 1
pool.currentFrame = 0
pool.maxFitness = 0
return pool
end
I know many basics of both languages and i know it works in lua but i need it in C++. Can anyone help me?
Lua has something called Tables which allows you to add key-value pairs without a predefined struct as in C/C++. So the Lua code you posted is adding key-value pairs to pool (read comments in code):
local pool = {} -- Declare a new Table
pool.species = {} -- Add another Table to pool called 'species'
pool.generation = 0 -- Add the key 'generation' with value '0'
pool.innovation = Outputs -- Add the key 'innovation' with value 'Outputs'
pool.currentSpecies = 1 -- Add the key 'currentSpecies' with value '1'
pool.currentGenome = 1 -- Add the key 'currentGenome' with value '1'
pool.currentFrame = 0 -- Add the key 'currentFrame' with value '0'
pool.maxFitness = 0 -- Add the key 'maxFitness' with value '0'
In C++ you have several options. 1) you can create a struct and declare what you need (I'm guessing on some datatypes but if you have the full Lua program you can figure them out):
struct Pool
{
Species species; // You'll have to define Species in another struct
int generation;
SomeEnum innovation; // You'll have to define SomeEnum in an enum
int currentSpecies;
int currentGenome;
int currentFrame;
int maxFitness;
}
If you have a class then you can use the struct Pool shown below (add the struct Pool definition from above to the .h file below above class Kingdom):
// I'm doing this as a class since you are programming in C++ and I
// assume you will want to add more functions to operate on similar
// objects.
class Kingdom
{
public:
Kingdom();
Pool* NewPool();
private:
Pool _pool;
}
In your .cpp file:
#include "Kingdom.h"
Kingdom::Kingdom()
{
// _pool.species = whatever you define struct Species as
_pool.generation = 0;
_pool.innovation = SomeEnum::Outputs; // You'll have to define SomeEnum
_pool.currentSpecies = 1;
_pool.currentGenome = 1;
_pool.currentFrame = 0;
_pool.maxFitness = 0;
}
Pool* Kingdom::NewPool()
{
Pool* newPool = new Pool;
memcpy(newPool, &_pool, sizeof(Pool)); // Make a copy
return newPool; // Return the new copy
// The newPool value is dynamic memory so when the calling function is done
// with newPool it should delete it, example:
// Kingdom myKingdom;
// Pool* myNewPoolStruct = myKingdom.NewPool();
// ... do some coding here
// delete myNewPoolStruct;
}
Option 2) would be if all of your key-value pairs were the same type; i.e. all keys were std::string and all values were int. Remember, the Lua code is using Tables so you can create the equivalent in C++ with std::map<>. Then you could use std::map<std::string, int> as follows:
// In your .h file change
Pool* NewPool();
Pool _pool;
// to
std::map<std::string, int> NewPool();
std::map<std::string, int> _pool;
Then in your .cpp file change the constructor to:
Kingdom::Kingdom()
{
_pool["species"] = 0; // Some int representation of species
_pool["generation"] = 0;
_pool["innovation"] = 1; // Some int representation of Outputs
_pool["currentSpecies"] = 1;
_pool["currentGenome"] = 1;
_pool["currentFrame"] = 0;
_pool["maxFitness"] = 0;
}
std::map<std::string, int> NewPool()
{
std::map<std::string, int> newPool;
newPool = _pool; // Copy - double check this against std::map
return newPool; // Double check this is a true copy and not a pointer
}
With std::map you can create key-value pairs on the fly just like the Lua code you provided. In short, I'd go with the struct Pool approach because with std::map<> you'll have to remember strings which isn't good practice and your IDE should have intellisense which will always show you the contents of struct Pool whenever you hit the . or -> operators.
Related
I use "xtensor" library for c++. With its help i try to create a datatable class that contain the user data.
Sometimes i need to subset some user group data by the users id list. For this task I use boolean flag system to mark users i want to copy to a new table.
class UserDataTable {
private:
xt::xarray<bool> which;
//... more code
}
UserDataTable::UserDataTable(int size){
//... more code
std::vector<std::size_t> shape(size, 1);
std::vector<bool> boolinit(size);
which = xt::adapt(binit, shape);
//... more code
}
In subset function there is this code:
for(int usercounter=0; usercounter<USER_LIST_COUNT; usercounter++){
std::string id = userlist(usercounter);
if(indexMap.count(id)>0){
int index = indexMap[id];
which(index) = true;
}
}
But this line of code:
which(index) = true;
assigns "true" value to all "which" array elements.
What am i doing wrong?
std::vector<bool> is a special case. operator[] returns reference std::vector<bool>::reference and
Any reads or writes to a vector that happen via a
std::vector<bool>::reference potentially read or write to the entire
underlying vector.
I am trying to access atomic private variables defined in class A using vector of objects . This vector of objects is passed by value in other class B defined in another header file. While retrieving the the value from vector I am getting the value as 0
I have few std::atomic private variables in a class say class A
A.hpp file
class A
{
public:
vector<A> updatePktCount();
private:
std::atomic pktCount;
std::atomic recvPkt;
std::atomic droppedPkt;
};
A.cpp
// there will be different pkts for different ports
vector a[2]; // 2 since I have 2 port ID's
vector<A> A::updatePktCount(int portId)
{ a.push_back(A());
//some function that gets packet details based on portId
pktCount = getPacketCount(int portID, int recvPkt,int pktCount,int droppedPkt);
pktCount = pktCount++;
recvPkt = recvPkt++;
droppedPkt = droppedPkt++;
a.push_back(A());
return a;
}
Class B in different header file B.hpp
class B: public A {
void getPacketCountFromA();
};
B.cpp file
void B::getPacketCountFromA()
{
vector<A> storeValue;
A a;
storeValue = a.updatePktCount();
for(auto i = storeValue.begin(); i != storeValue.end(); ++i)
{
// print values
}
}
I have created a vector of objects in A like vector<A> a[2] for 2 portId but when I retrieve this vector in getPacketCountFromA I am getting the vector size as 2 but all the values in the vector is 0
Am I doing anything wrong here ?
Result
size of vector is 2
pktCount = 0
recvPkt = 0
droppedPkt = 0
recvPkt = recvPkt++; is retrieving the value of recvPkt, increment recvPkt, then store the retrieved value (0) back into recvPkt, losing the effect of the increment. Just increment the value:
++recvPkt;
The same for your other variables.
Assume I have a class:
class A {
public:
int key;
map<int,int> a;
};
Obj_A1 is an existing object of class A. Somewhere in my problem, I want to construct another object called Obj_A2 and update the members of Obj_A2 like this:
Obj_A2.key = Obj_A1.key + 1;
Obj_A2.a = Obj_A1.a; // When a is large, this copy operation will be really time consuming.
So I try to get around the real data transfer, considering that maybe I can assign the address of Obj_A2.a with the address of Obj_A1.a. In case, Obj_A2.a is just Obj_A1.a in the memory, and there is not data duplication at all.
So I did something silly (I am new to C++), which is, &Obj_A2.a = &Obj_A1.a, and had some compiler error.
Does anyone know the right way to do this?
Thanks a lot.
It sounds like you want a shared pointer.
#include <memory>
#include <map>
class A {
public:
int key;
std::shared_ptr<std::map<int,int>> a;
};
int main() {
A Obj_A1, Obj_A2;
Obj_A1.key = 0;
Obj_A1.a = std::make_shared<std::map<int,int>>();
Obj_A2.key = Obj_A1.key + 1;
Obj_A2.a = Obj_A1.a;
// or, more simply
// Obj_A2 = Obj_A1;
// Obj_A2.key++;
}
With this, Obj_A2.a will point to the same map as Obj_A1.a, and modifications to the map from one will be seen by the other.
class A {
public:
int key;
map<int,int> *a;
};
...
Obj_A1.a = new map<int,int>;
...
Obj_A2.key = Obj_A1.key + 1;
Obj_A2.a = Obj_A1.a;
I have written a function in c++ which receives a struct as a input. The struct object received has two arrays. I need to use both the arrays for different purposes. The array names have been created in a certain format. How to retrieve array names in a string.
struct INFO
{
float fADataLHS[3] = {1,2,3};
float fADataRHS[3] = {4,5,6};
Struct INFO has been defined where two arrays have been defined an initialized. The function useStruct uses both the function for different purposes.
void useStruct(struct *INFO)
{
--------;
--------;
}
int main()
{
struct INFO info;
useStruct(info);
}
I want a method in which I can retrieve the name of the array as for ex. fAdataLHS and store it to a string. The idea is to find the sub-string LHS and RHS from the string names and process then accordingly.
PS: I am quite new to c++.
I will go simple as you're a begginer to C++.
If you want to use both of arrays for different purposes, just doit. For instance:
void use_array_for_different_purposes(INFO *info)
{
// Purpose one, printing values using fADataLHS.
for (int i = 0; i < 3; i++) {cout << info->fADataLHS[i] << endl;}
// Purpose two, computing total sum using fADataRHS.
int acum;
for (int i = 0; i < 3; i++) {acum += info->fADataRHS[i];}
}
As you can see, you don't need to get the arrays names as strings values.
If I understand corectly, your use case is this: you have two (or more) names and each has a float array associated with it. You want to get the array by name and process the data.
Consider this code:
class INFO
{
std::map<std::string, std::vector<float>> vectors;
public:
INFO() : vectors{}
{
vectors["fADataLHS"] = { 1, 2, 3 };
vectors["fADataRHS"] = { 4, 5, 6 };
}
const std::vector<float>& operator[](const std::string& key) const // access vector by key
{
return vectors.at(key);
}
};
void useStruct(const INFO& info) // pass instance by const reference
{
std::cout << info["fADataLHS"][0] << "\n"; // access element 0 from the fADataLHS array
// get the entire array:
const auto& arr = info["fADataRHS"];
// this will throw a std::out_of_bounds
const auto& arr = info["non-existent-key"];
}
EDIT: A few other notes:
in C++ try not to use float - use double instead
if you need to alter the vector contents from client code, add a non-const version of the operator[]
Is it possible to set a member attribute in a "generic" way?
I am still new to c++ and just dived into templates, if this is the way to go?
The class i have to use has around 20 string members to be filled from informix database and i could loop through an array with the field(=attribute) names.
Let's say i have a simple class
class Foo
{
public:
attr1
attr2
Foo() { };
~Foo();
}
and i could use it like that:
Foo foo;
string myattr = "attr1";
string myval = "val x1";
string myval = "val x2";
setattribute( foo, myattr, myval1 ); // pseudocode... possible somehow?
cout << foo.attr1; // prints "val x1"
setattribute( foo, myattr, myval2 ); // pseudocode... possible somehow?
cout << foo.attr1; // prints "val x2"
The method i call in the loop could look like this...
// its_ref : empty string reference
// row: ptr on the current db row = query result object
// colname: the db column = attribute
// ki: the object
void get_fd( ITString & its_ref, ITRow * row, ITString colname, ns4__SOAPKunde& ki ) {
ITConversions *c;
ITValue *v = row->Column( colname );
v->QueryInterface(ITConversionsIID, (void **) &c);
c->ConvertTo( its_ref );
// here is the place i want to use it :
setattribute( ki, colname, its_ref.Data() );
}
You can use member data pointers. These can be of any type- e.g.
struct x {
int y;
int z;
};
int main() {
int x::* res = &x::y;
}
However, if you want to start accessing them by identifier at runtime, you will have to build your own system from scratch.
The only option I can think of would be to store you attributes in a map of boost::any. With the assumption that you want your attributes to be of heterogeneous types.
The basic idea is to replace your attributes in Foo with map. So instead of having all your private attributes you would have a map that wraps them. The problem with C++ is that your attribute names don't exist after compiling the program (unlike other scripted languages like python). So there is no way to access an attribute variable from a string representing it's name without using some kind of data structure
removed old edit_
You could use a std::map.
The (base) class of 'ki' then has to implement setattribute like this:
// Member variable of MyClass
std::map<string, string> mProps;
void MyClass::setattribute( const char * name, const char * value )
{
mProps[name] = value;
}