I am learning about c++ and was following a course. A final exercise involves making a program for deck of cards. I have thought of an approach:
I initially tried to do everything with string arrays but realised that it would make more sense to use vectors since. I am now trying to create a std::vector std::string out of my std::string array but with no luck.
I have found some example code online such as:
from https://thispointer.com/5-different-ways-to-initialize-a-vector-in-c/
And tried to implement it for my program, however, I cannot get it to work and cant fully understand what is the issue.
My code:
#include <iostream>
#include <string>
#include <vector>
class card_deck {
public:
card_deck();
std::vector<std::string> deal_hand(int num_cards);
void new_deck();
private:
//std::vector<std::string> cards_vector;
std::string cards[52] =
{
"As","2s","3s","4s","5s","6s","7s","8s","9s","Ts","Js","Qs","Ks",
"Ah","2h","3h","4h","5h","6h","7h","8h","9h","Th","Jh","Qh","Kh",
"Ad","2d","3d","4d","5d","6d","7d","8d","9d","Td","Jd","Qd","Kd",
"Ac","2c","3c","4c","5c","6c","7c","8c","9c","Tc","Jc","Qc","Kc"
};
std::vector<std::string> cards_vector(cards, sizeof(cards)/sizeof(std::string) );
};
As you can see from my code, I initialize a string array in my private variables, and then want to convert this string array to std::vector
The error message returned:
UPDATE
Code works when called in main()
int main()
{
std::string cards[52] =
{
"As","2s","3s","4s","5s","6s","7s","8s","9s","Ts","Js","Qs","Ks",
"Ah","2h","3h","4h","5h","6h","7h","8h","9h","Th","Jh","Qh","Kh",
"Ad","2d","3d","4d","5d","6d","7d","8d","9d","Td","Jd","Qd","Kd",
"Ac","2c","3c","4c","5c","6c","7c","8c","9c","Tc","Jc","Qc","Kc"
};
// Initialize vector with a string array
std::vector<std::string> vecOfStr(cards, cards + sizeof(cards) / sizeof(std::string));
for (std::string str : vecOfStr)
std::cout << str << std::endl;
}
Does not work when used in class
#include <iostream>
#include <string>
#include <vector>
class card_deck {
public:
card_deck();
std::vector<std::string> deal_hand(int num_cards);
void new_deck();
private:
std::string cards[52] =
{
"As","2s","3s","4s","5s","6s","7s","8s","9s","Ts","Js","Qs","Ks",
"Ah","2h","3h","4h","5h","6h","7h","8h","9h","Th","Jh","Qh","Kh",
"Ad","2d","3d","4d","5d","6d","7d","8d","9d","Td","Jd","Qd","Kd",
"Ac","2c","3c","4c","5c","6c","7c","8c","9c","Tc","Jc","Qc","Kc"
};
// Initialize vector with a string array
std::vector<std::string> vecOfStr(cards, cards + sizeof(cards) / sizeof(std::string));
for (std::string str : vecOfStr)
std::cout << str << std::endl;
};
int main()
{
}
Easy way:
std::vector<std::string> cards {
"As","2s","3s","4s","5s","6s","7s","8s","9s","Ts","Js","Qs","Ks",
"Ah","2h","3h","4h","5h","6h","7h","8h","9h","Th","Jh","Qh","Kh",
"Ad","2d","3d","4d","5d","6d","7d","8d","9d","Td","Jd","Qd","Kd",
"Ac","2c","3c","4c","5c","6c","7c","8c","9c","Tc","Jc","Qc","Kc"
};
and drop the separate cards_vector member. cards.size() yields the number of elements in the vector.
This uses the initialiser-list syntax of C++11.
And the compiler works out the size for you: handy if you need to add the jokers in later for example.
I'm having a hard time trying to understand how to use the <initializer_list> in C++. Let's pick a simple example:
I've got something like this:
using namespace std;
class TV{
vector<string> channels;
public:
TV(initializer_list<string> channels){}
}
Let's say this is my main:
int main(){
TV x({"BBC", "CNN"}, y({"SKYNEWS", "FOX", "CNN"});
return 0;
}
How can I create a constructor without default argument-count for strings?
One of the constructors of std::vector directly takes a std::initializer_list
vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );
So you can just initialize in your constructor
TV(std::initializer_list<std::string> _channels)
: channels(_channels)
{}
Also you should avoid declaring multiple variables on a single line, as your parentheses were mismatched, it would have been more obvious.
TV x{{"BBC", "CNN"}};
TV y{{"SKYNEWS", "FOX", "CNN"}};
Working demo
Your code is working fine.
There is braces misalignment in TV x({"BBC", "CNN"}), y({"SKYNEWS", "FOX", "CNN"}); ,while you declared. Adjusted and pasted the code below. It works.
#include <iostream>
#include <vector>
using namespace std;
class TV{
vector<string> channels;
public:
TV(initializer_list<string> channels1){
channels = channels1;
}
void printSize()
{
cout<<channels.size()<<endl;
}
};
int main(){
TV x({"BBC", "CNN"}), y({"SKYNEWS", "FOX", "CNN"});
x.printSize();
y.printSize();
return 0;
}
The output is
2
3
im new in c++ (and not to old in programming...) and i have problem with handling vectors and strucs in class.
basically i have a vector and a array of pointers to struct members in the class and i want work on the in my methos but im doing something worng/
here is my movement.h
#pragma once
using namespace std;
class movement
{
private:
static const int MAX_ROW_PER_TRACKER = 100;
static const int MIN_TO_START_CALC = 30;
static const int MAX_TRACKERS = 20;
struct tracker
{
int id;
double a[MAX_ROW_PER_TRACKER];
double b[MAX_ROW_PER_TRACKER];
double c;
};
vector<int> trackersOrder[MAX_TRACKERS] = {};
tracker* trackersArr[MAX_TRACKERS];
public:
movement();
void addRow(int a, int b, int c);
~movement();
};
and my movement.cpp
#include "stdafx.h"
#include "movement.h"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
movement::movement()
{
}
void movement::addRow(int id, int a, int b)
{
int index;
vector<int>::iterator searchID = find(trackersOrder.begin(), trackersOrder.end(), ID);
if (searchID == trackersOrder.end())
{
vector<int>::iterator freeLocation = find(trackersOrder.begin(), trackersOrder.end(), 0);
index = freeLocation - trackersOrder.begin();
trackersOrder.insert(trackersOrder.begin + index, id);
structArr[index] = new tracker;
structArr[index]->id = id;
structArr[index]->a[0] = a;
structArr[index]->b[0] = b;
structArr[index]->c = 0;
}
}
movement::~movement()
{
}
so when i send to method "addRow" id, and b i want to first check if i allready have this id in my vector (the vector just give me the index for the structs array) and if not then if put the id in the first empty place in the vector and on the structs array/
but from some reasin its look to me that the methid dont reconized the vector and the structs. can you help me understand why?
p.s - i can bet that i have more mistakes in my code, its my firs try with pointers and ect. (im comming from the good life in Matlab) so i will be happy to learn on them also
thank you very much!
The main problem
The problem is that in your code, trackersOrder is not a vector but an array of vectors:
vector<int> trackersOrder[MAX_TRACKERS] = {}; // array of MAXTRACKERS vectors !!
The solution
If you define it as simple vector, it should work better:
vector<int> trackersOrder;
If you want to set its size do it in the movement constructor:
movement::movement() : trackersOrder(MAX_TRACKERS)
{
}
Other issues
There is a case typo with an ID that should be id.
auto searchID = find(trackersOrder.begin(), trackersOrder.end(), id); // by the way auto is easier + ID corrected
There are a missing () after a begin whicn transforms unfortunately your iterator arithmetic into function pointer arithmetic (sic!!):
trackersOrder.insert(trackersOrder.begin() + index, id); // corrected
Finally, there are a couple of structArr that should be replaced by trackersArr.
The result does finally compile (online demo)
I could not declare an array of strings in my class. Below my class definition:
class myclass{
public:
int ima,imb,imc;
string luci_semaf[2]={"Rosso","Giallo","Verde"};
};
and my main file
#include <iostream>
#include <fstream>
#include "string.h"
#include <string>
using namespace std;
#include "mylib.h"
int main() {
return 0;
}
Why do I get the following warnings / error?
You have two problems: The first is that you can't initialize the array inline like that, you have to use a constructor initializer list. The second problem is that you attempt to initialize an array of two elements with three elements.
To initialize it do e.g.
class myclass{
public:
int ima,imb,imc;
std::array<std::string, 3> luci_semaf;
// Without C++11 support needed for `std::array`, use
// std::string luci_semaf[3];
// If the size might change during runtime use `std::vector` instead
myclass()
: ima(0), imb(0), imc(0), luci_semaf{{"Rosso","Giallo","Verde"}}
{}
};
You can not initialize data member.
You can write like this:
class myclass{
public:
myclass() {
luci_semaf[0] = "Rosso";
luci_semaf[1] = "Giallo";
luci_semaf[2] = "Verde";
}
private:
int ima,imb,imc;
string luci_semaf[3];
};
You can assign the values of the array in the Сonstructor
You're declaring an array of size 2 but providing 3 strings!
Try storing the elements in vector of strings, in c++ vectors are used more often.
class myclass{
public:
int ima,imb,imc;
std::vector<std::string> strings;
myclass() {
strings.push_back("blabla");
}
};
I have to use cross platform code. And right now , I am stuck using VS2012 , which does not support C++11 , uniform initialization. So , I am using boost::list_of.
For simple cases, this works. However, for a slightly complicated data structure , this does not seem to work.
#include <iostream>
#include <boost/assign.hpp>
#include <boost/assign/list_of.hpp>
#include <tuple>
using namespace std;
using namespace boost::assign;
int main() {
class NodeInfo
{
public:
NodeInfo (int Parent, int childLeft, int childRight) :
m_parent (Parent), m_childLeft(childLeft), m_childRight(childRight)
{
}
private:
int m_parent;
int m_childLeft;
int m_childRight;
};
typedef std::vector<NodeInfo> MyData1;
MyData1 expData = list_of(NodeInfo(1,2,3)) (NodeInfo(3,4,5));
typedef std::tuple<int , std::vector<NodeInfo>> MyData2;
MyData2 expData21 = std::make_tuple(10 , expData);
// I would have really liked the following:
// error:
MyData2 expData22 = std::make_tuple(10 , list_of(NodeInfo(1,2,3) (NodeInfo(3,4,5) )));
//error:From the example in boost doc, this should work.
MyData2 expData3 = list_of<MyData2> (std::make_tuple(10 , expData));
MyData2 expData4;
// error: Most probably need to write my own list_inserter for MyTest,
// after turning MyTest into a class.
// I really don't want to go this route, if the other options are at all
// possible. Why extend the boost library, if it's at all possible ?
insert( expData4 )
( std::make_tuple(10 , expData) )( std::make_tuple(20 , expData) );
return 0;
}
I have added a partial code here.
https://ideone.com/kIYDu0
Indeed, the best way to make this work smoothlessly is to extend the library (or just write your own helper functions).
However, the things you try were never features. The documentation shows how to assign from list_of to a vector:
Tuple mytuple2 = std::make_tuple(10,
list_of(NodeInfo(1, 2, 3))(NodeInfo(3, 4, 5)).to_container(std::get<1>(mytuple2))
);
More notes:
Looks to me you forgot to make expData3 and expData4 a container.
at some point you use std::make_tuple(1,2,3) as a NodeInfo. I don't see how that should work
Here's the full lists with fixes/workarounds:
Live On Coliru
#include <iostream>
#include <boost/assign.hpp>
#include <boost/assign/list_of.hpp>
#include <tuple>
using namespace std;
using namespace boost::assign;
int main() {
class NodeInfo {
public:
NodeInfo(int Parent, int childLeft, int childRight)
: m_parent(Parent), m_childLeft(childLeft), m_childRight(childRight) {}
private:
int m_parent;
int m_childLeft;
int m_childRight;
};
typedef std::vector<NodeInfo> NodeInfos;
NodeInfo node1(1,2,3), node2(3,4,5);
NodeInfos infos = list_of(node1)(node2);
typedef std::tuple<int, std::vector<NodeInfo> > Tuple;
Tuple mytuple = std::make_tuple(10, infos);
// I would have really liked the following:
Tuple mytuple2 = std::make_tuple(10,
list_of(NodeInfo(1, 2, 3))(NodeInfo(3, 4, 5)).to_container(std::get<1>(mytuple2))
);
std::vector<Tuple>
mytuples = list_of<Tuple>(std::make_tuple(10, infos)),
mytuples2;
//// still figuring this out:
// insert(mytuples2)(Tuple(10, infos))(Tuple(20, infos));
}
// I would have really liked the following:
// error:
MyData2 expData22 = std::make_tuple(10 , list_of(NodeInfo(1,2,3) (NodeInfo(3,4,5) )));
You just got the parentheses wrong. The following should work:
MyData2 expData22 = std::make_tuple(10 , list_of(NodeInfo(1,2,3))(NodeInfo(3,4,5)));