Using a list inside a struct c++ - c++

I´m starting with the programming and i speak bad english sorry for that.
I like to use a list instead of an array, inside of a struct, something like this:
#include <iostream>
#include <list>
using namespace std;
struct Market {
string b;
list <int> prices;
};
int main()
{ list <int> precios;
Market m1 = {"a",NULL};
return 0;
}
but i get this error conversion from int' to non-scalar type std::list<int, std::allocator<int> > requested|
Is this possible? maybe with malloc or free?

You should define a constructor
struct Market {
Market(string val){b=val;}
// or like this:
// Market(string val):b(val){}
string b;
list <int> prices;
};
Then you will be able to create objects like:
Market a("A");
As lists default constructor creates empty list, you dont need to pass it any parametrs.
A good read about basics of classes: http://www.cplusplus.com/doc/tutorial/classes/

NULL is not of the type std::list<int>, that's why you are getting this error.
Are you using a C++11 compiler?
If yes then try:
Market m1 = {"a", { NULL } };
Otherwise:
list<int> prices;
Market m1;
m1.b = "a";
m1.prices = prices;

You are attemping to initialize the list with a null pointer value (actually an int type). If you need to store the list by value you can initialize 'm1' like so
Market m1 = {"a", std::list<int>()};

Related

vector<string> vs string[] when passing to function

I'm new to C++ and I'm trying to pass a collection of a nonvariable amount strings to a function that exists in separate class file in an easy to read manner as such:
//main in Caller.cpp
int main()
{
string details[] = {"Name","Height","Weight"};
/* vector<string> detailsV = {"Name","Height","Weight"};
* Would like to use a vector but can't do this because vector cannot be
* initialized to = {...} in C++
*/
Person p = Person();
p.inspectDetails(details);
}
//Person class in Person.cpp
void inspectDetails(string details [])
{
int sz = sizeof(details); // this will result in details = "Name" only
}
I've tried:
//Person class in Person.cpp
<template size_t N>
void inspectDetails(string (&details)[N])
{
int sz = sizeof(details);
}
However, I don't now how to let the main in the Caller class know about the <template size_t N> which might allow me to use an array of a non-explicit amount. I seem to get an error of "no suitable conversion of std:string[3] to std:string" when trying to call inpectDetails this way.
What is the best way to pass a collection of strings of a non-explicit amount to a function outside of the Caller class whilst maintaining the ability to hardcode the collection's contents like so Collection c = {"...", "...", "..."} in C++?
Is there an easier way to pass the full collection of strings to a function with a pointer to a vector or something of that sort?
Use a std::vector< std::string > and pass it by reference if you need to change its contents, const reference if you don't need to change them. This is the simplest, most flexible, and clearest way.
Thus:
void inspectDetails( std::vector< std::string > & details );
std::vector< std::string > details = { "Name","Height","Weight" };
inspectDetails( details );
cf. http://en.cppreference.com/w/cpp/container/vector
Passing by const reference is an option. This is what a possible program might look then:
#include <iostream>
#include <string>
#include <vector>
void inspectDetails( const std::vector<std::string> & details )
{
int v = details.size();
std::cout<<v<<std::endl;
}
int main()
{
std::vector<std::string> details = {"name", "height", "weight"};
inspectDetails(details);
return 0;
}
Rob K answered right to you question. I will add that sometimes it's usefull to use std::array rather than a simple array : http://en.cppreference.com/w/cpp/container/array For example, you can easily know the size of your array.

End process error code -1 if acess to string field of structure

#include <cstdlib>
#include <string>
#include <iostream>
#define S 10
using namespace std;
struct List
{
string name;
bool male;
int year;
string addr;
string diag;
bool hosp;
};
main()
{
struct List *l=NULL;
int n=0;
for(int i=0;i<10000;i++)
{
if(!(n%S))
{
l=(List*)realloc(l,(n/S+1)*S*sizeof(struct List));
cout<<"realloc ok\n";
};
l[n].male=rand()%2;
l[n].year=1900+rand()%100;
l[n].hosp=rand()%2;
//!l[n].name="abc";
n++;
cout<<l[rand()%n].male<<" "<<l[rand()%n].year<<" "<<l[rand()%n].hosp<<endl;
}
}
If l[n].name="abc" remarked then program works fine.
If i try put string value to this field the programm compiled without warnings nay, but crash with error code -1 after first realloc.
Any way to solve it?
Since your structure is non-trivial - it contains members of class type, std::string, which need to be initialised by calling their constructors - you can't simply allocate raw memory and pretend that contains a valid object.
The simplest solution is to use a type-aware dynamic array
std::vector<List> l;
which can be resized, perserving its contents, with
l.resize((n/S+1)*S);
Tip! Using "new" operator to allocate this structure will automatically create string object for each field.
List *l=new struct List[S];
It fix this issue, l[n].name="abc" will works, but it not implements reallocation functional.

Dynamic C++ Map <String, Primitives (int, double, string, or array)>

My apologies in advance, but I can't find this one.
In C++ I want a have a map. This map will consist of <string, Object>; where the objects are added dynamical from an XML document during runtime. The Object will either be a int, double, string, or array of ints, doubles, or string. The key is guaranteed to be unique. However, I need a way to dynamically declare this using a map.
Is this perhaps an instance when I should be using a template for the data part?
I can't use a large lib such as boost to achieve this, since this should be a light wight program.
(Ref: Use boost C++ libraries?)
This is similar to what im trying to achieve. Where the user specified the primitive type: (Ref: Creating dictionary that map type T as key to instance of type T)
std::map <std::string, ????> Values;
Edit:
So if I can't use boost, could I achieve this using a template?
In boost I am dong this:
typedef boost::variant<int, double, std::string> datum;
std::map<std::string, datum> Parms;
Then I later adding values during run-time (from XML, where each element has an attribute with the specified type)
Parms["a"] = 10; // int
Parms["b"] = 102.2039; // double
Parms["c"] = 6.6667e-07; // another double
Parms["d"] = "Hello world"; // std::string
The problem is when I do this:
datum v1 = obj.get("c"); // need double, not datum
You could consider embedding your primitive type in a struct. You can define a base class from which the different structs are derived. You probably need to save the type as well into the struct, but I left it out for simplicity.
If you really need the primitive types, ignore my answer and go for Boost.
#include <map>
#include <string>
struct BaseObject {};
struct ObjectInt : public BaseObject
{
int a;
};
struct ObjectString : public BaseObject
{
std::string a;
};
int main()
{
BaseObject *oi, *os;
oi = new ObjectInt;
os = new ObjectString;
std::map<std::string, BaseObject *> objectMap;
objectMap["oi"] = oi;
objectMap["os"] = os;
delete oi;
delete os;
return 0;
}

Creating a vector of structures, reserving space, C++

Here is my structure declaration:
struct HeapEntry {
HeapEntry(int a, int b){
id = a;
key = b;
}
int id;
int key;
};
I'd like to make a vector to store HeapEntry objects, and reserve memory for it since I know how many object I'll need to store.
std::vector<HeapEntry> adjList();
adjList.reserve(200);
The adjList.reserve(200) line produces the error "expression must have class type" though. what going on here?
Thanks
use:
std::vector<HeapEntry> adjList;
instead of this:
std::vector<HeapEntry> adjList();
Did you mean to declare it like this?
std::vector<HeapEntry> adjList;

Array of values within an ENUM?

I have this code
enum type {NOTHING, SOMETHING, SOMETHINGELSE}
type *x;
At the moment I use x[765] == SOMETHING for example, How would I store other values for example
x[765] == SOMETHINGELSE;
x[765].position == 43.5;
x[765].somevar == 12;
I will apologize for my poor wording within my question im just starting out in C++, I know what I want i'm just not to sure on how to ask it.
Thanks.
It looks as if you're looking for a way to structure 'knowledge'; this is done with a struct or a class:
#include <vector>
struct Info {
enum thingness { nothing, something };
// 'member' variables
thingness howMuch;
int a_counter;
float position;
};
int main(){
Info object;
object.howMuch=Info::something;
object.a_counter=1;
object.position=5.4;
You can group these kinds of objects into a container - typically an std::vector:
// a container of InterestingValues
std::vector<Info> container(300);
container[299].howMuch=Info::nothing;
container[299].a_counter=4;
container[299].position = 3.3;
// or assign rightaway:
container[2] = object;
}
You will have to make yourself a more complex type:
struct type
{
enum flag_type
{
NOTHING, SOMETHING, SOMETHINGELSE
} flag;
double position;
int somevar;
};
and later have an array of this new type.
Get yourself a good book to learn from. A list of good books is available here: The Definitive C++ Book Guide and List
In C++, you are asking how to declare an array of structures. Try this:
struct type {
double position;
int somevar;
};
type *x;
x[765].position = 43.5;
x[765].somevar = 12;
An enum is a replaceable label basically for an int. You need to define a struct or a class.
struct type
{
float position ;
};
type var;
var.position = 3.4;
Your type enum would need to be a member of a class, along with the other fields. For example,
class MyType
{
public:
type t;
double position;
int somevar;
};
With an array of MyType instances
MyType *x;
you would then be able to do what you ask expect you would need to do
x[765].t = SOMETHINGELSE;
to assign to the enum.