Structure with vectors - c++

I have some problems with sending structure to function:
Here is my main.cpp file:
#include "stdafx.h"
#include "vehicles.h"
#include <iostream>
#include "tools.h"
#include <time.h>
#include <vector>
using MAP_GRID = vector<vector<string>>;
using namespace std;
void print_terrain(MAP_GRID);
void set_position(MAP_GRID &, int, int, position &, string);
void random_position(MAP_GRID &, int, string);
MAP_GRID create_terrain();
MAP_GRID MAP = create_terrain();
int _tmain(int argc, _TCHAR* argv[])
{
tanks t34(12, 0.5, 21,6);
srand(time(NULL));
set_position(MAP, 5, 5, player,"[x]");
//[...]
}
Here is another file, with definition of this function:
#include "stdafx.h"
#include <iostream>
#include <vector>
#define MIN_SIZE 6
#define MAX_SIZE 15
using std::vector;
using std::string;
using MAP_GRID = vector<vector<string>>;
int global_size;
struct position{
vector<int> x;
vector<int> y;
};
void set_position(MAP_GRID &MAP, int x, int y, position &pos, string object)
{
if (x <= MAP.size() || y <= MAP.size())
if (MAP[x][y] != "[ ]")
std::cout << "\nPosition is occupied" << std::endl;
else
{
MAP[x][y] = object;
pos.x.push_back(x);
pos.y.push_back(y);
}
else
std::cout << "\Choose correct position" << std::endl;
}
This structure have to hold coordinate of some point (numbers of these points depends of object).

This has nothing at all to do with vectors (as you'd have discovered, had you constructed a minimal testcase during your many days of painstakingly debugging this problem).
You have to at least declare identifiers in every translation unit you want to use them in, before you use them.
You have not done that, so the compilation of main.cpp will fail because, indeed, it has no idea what position is supposed to be. player is, likewise, a complete mystery.
Typically we define types in "header files", making for easy inclusion of these definitions across multiple translation units. In this case, you can at least get away with a forward declaration of position.

Related

How to declare a <vector> object and use push_back inside a class?

I'm trying to build a class named "Tombola" which should contain as private variable an empty vector. This should be filled at runtime through the class member Tombola.estrai(), which generates a random number and insert it inside the vector named "order" by the method order.push_back(number). This is the class definition in the tombola.h header:
#ifndef TOMBOLA_H
#define TOMBOLA_H
#include <cstdlib>
#include <vector>
using namespace std;
class Tombola {
private:
bool on_off[90];
int tabellone[9][10];
int x_max = 9;
int y_max = 10;
vector<int> order;
public:
Tombola();
~Tombola();
void nuovo();
int estrai();
bool completato();
void stampa();
void stampa_tab();
};
#endif
And this is the implementation of constructor/destructor and Tombola::estrai() inside tombola.cc:
#include "tombola.h"
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <vector>
#include <iostream>
using namespace std;
Tombola::Tombola () {
vector<int> ord;
order = ord;
int z=1;
for(int i=0;i<90;i++) {
on_off[i] = false;
}
for(int j=0;j<=x_max;j++) {
for (int k=0;k<=y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
}
Tombola::~Tombola() {
cout << "Tombola is destroyed" << endl;
}
int Tombola::estrai() {
srand(time(NULL));
int estrazione = int(ceil(rand()/double(RAND_MAX)*90));
on_off[estrazione]==true;
order.push_back(estrazione);
return order.back();
}
and this is the call to the method in the main.cpp file:
#include "tombola.h"
#include <cstdlib>
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
int main () {
Tombola natale;
cout << natale.estrai();
}
When I compile the program everything goes fine, but when I execute the main I get a segmentation fault error which seems to be due to some sort of allocation error when trying to store the item inside the order vector, as reported by the debugger. Could someone explain to me how to solve the error and why the error occours? Thank you.
The reason of segmentation fault is in the constructor. You have to change for(int j=0;j<=x_max;j++) to for(int j=0;j<x_max;j++) in order not to cross the bounds of the array.
for(int j=0;j<x_max;j++) {
for (int k=0;k<y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
However, there are also some minor issues in the code that are worth being mentioned
declaring default-initialized ord vector and assigning it to order is pointless because order is already default-initialized.(See member initializer list for more information).
using namespace std; in a header file is a terrible idea, because if you had a large codebase, and had multiple source files where you want to include that header, everywhere the using statement will be applied, which probably is not desired.

Printing the first value from more than one vector in C++

I am trying to print the first value from each vector shown below in the main function.
#include <iomanip>
#include <map>
using namespace std;
typedef unsigned int vect;
int main() {
std::vector<vect> p;
vector<vect> a = { 4,2,3,1 };
vector<vect> b = { 4,2,3,1 };
vector<vect> c = { 4,2,3,1 };
vector<vect> d = { 4,2,3,1 };
int i;
for (i=0; i<a.size(); i++)
cout << a[i];
}
Function first_preference() from my function.cpp shown below
#include "function.h"
#include <string>
#include <iostream>
using namespace std;
person test::first_preference() const {
const person& first = p.front();
return first; //current first pref
}
The function is declared in this header class
#ifndef FUNCTION_H
#define FUCNTION_H
#include <vector>
typedef unsigned int person;
typedef unsigned int vect;
std::vector<vect> p;
class test {
public:
person first_preference() const;
};
#endif
I want the function first_preference() to be called from main() where the function should print the first value of each vector, how would I go about this?
I want the function first_preference() to be called from main() where the function should print the first value of each vector
Some issues:
You have a global std::vector<vect> p in your header file (which is not a good idea to begin with) which is shadowed by std::vector<vect> p in main. What you put in the p in main will not be accessible from instances of test. Those instances only knows about the global p.
You don't #include "function.h" in main.cpp so you can't create test objects in main.
If you #include "function.h" in main.cpp there's no need to typedef unsigned int vect; since you did that in function.h already. It's not an error, but confusing and unnecessary.
The vector<vect> instances a, b, c and d have no connection with test or any of the ps whatsoever so what you put in those vectors can't possibly be printed by instances of test unless you pass them on to test somehow.
You declare vectors of vect but first_preference() returns a person by value. vect and person happen to be aliases of the same fundamental type, but it seems like there is something wrong with this interface.
In main.cpp you don't instantiate a test, you iterate over a and first_preference() is never called so there's no hope for it to be used.
Why is “using namespace std;” considered bad practice?

C++ - Can I use extern and const at the same time with several files?

The thing is that I am trying to have a global constant variable for all the .hand .cpp files, but when I do this I got the error:
array bound is not an integer constant before ‘]’ token
I do not understand this because Z is a constant. When I do this with just one file it works. What am I doing wrong?
Number.h
#include <iostream>
extern const int Z;
a.cpp
#include <iostream>
#include "b.h"
#include "c.h"
#include "Number.h"
using namespace std;
int main() {
const int Z = 5;
b Objeto1;
c Objeto2;
double H[Z][Z];
Objeto1.Algo(H);
Objeto2.Imprimir(H);
return 0;
}
b.h
#include <iostream>
#include "Number.h"
class b {
public:
void Algo(double[Z][Z]);
};
b.cpp
#include <iostream>
#include "b.h"
#include "Number.h"
using namespace std;
void b::Algo(double H[Z][Z]) {
for(int a = 0; a < Z; a++) {
for(int b = 0; b < Z; b++) {
H[a][b] = Z;
cout << H[a][b] << endl;
}
}
}
c.h
#include <iostream>
#include "Number.h"
class c {
public:
void Imprimir(double H[Z][Z]);
};
c.cpp
#include <iostream>
#include "c.h"
#include "Number.h"
using namespace std;
void c::Imprimir(double V[Z][Z]) {
cout << "dfs" << endl;
}
I know that the code does not make any sense, but I am just trying to understand how I could have a constant for all the files. I really appreciate your help.
Use of
extern const int Z;
is perfectly fine. However, you can't use Z to define an array. Hence, use of Z in the following line, and similar other lines, is incorrect.
class b{
public:
void Algo(double[Z][Z]);
};
The size of arrays must be known at compiler time. With the extern declaration you have provided, that is not true.
The use of extern const is justified only when you wish to define the value at run time and expect the value to not change until the program ends.
If you simply wish to use it as a token for defining arrays, remove the extern and set its value also. Use:
const int Z = 5;

Use of BOOST_GEOMETRY_REGISTER_RING

I have trouble understanding how to register my own type as a boost::geometry::model::ring. I have my own point class:
struct Point { double x, y; };
And rings are stored as std::vector<Point>. I therefore registered them like this:
BOOST_GEOMETRY_REGISTER_POINT_2D(Point , double, cs::cartesian, x, y);
BOOST_GEOMETRY_REGISTER_RING(std::vector<Point>);
Now I would like to correct the orientation of a ring, and indeed, the following compiles:
void foo(std::vector<Point>& ring) {
boost::geometry::correct(ring);
}
Trouble is, how can I define the "correct" orientation of a ring? It's more obvious when using boost::geometry::model::polygon, where a template parameter allows me to specify the expected orientation. However, the following does not compile:
void foo(std::vector<Point>& ring) {
typedef boost::geometry::model::polygon<vector> clockwise_closed_polygon;
clockwise_closed_polygon cwcp;
boost::geometry::exterior_ring(cwcp) = ring; //<<< fails to compile
boost::geometry::correct(cwcp);
}
Apparently, my own ring type cannot be converted to the one defined by clockwise_closed_polygon.
So I have two questions:
How can I specify the correct ring orientation?
Why can't my ring type be used with the polygon, as declared above?
Trouble is, how can I define the "correct" orientation of a ring?
You may try to specialize boost::geometry::point_order:
live demo
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry.hpp>
#include <iostream>
#include <ostream>
#include <vector>
using namespace boost::geometry;
using namespace std;
struct Point { double x, y; };
BOOST_GEOMETRY_REGISTER_POINT_2D(Point , double, cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_RING(vector<Point>)
namespace boost { namespace geometry
{
template<>
struct point_order<vector<Point>>
{
//static const order_selector value=counterclockwise;
static const order_selector value=clockwise;
};
}}
template<typename Ring>
void print(const Ring &r)
{
for(auto p : r)
cout << "(" << p.x << "," << p.y << ")";
cout << endl;
}
int main()
{
std::vector<Point> ring{{0.0,0.0},{1.0,0.0},{0.0,1.0},{0.0,0.0}};
print(ring);
correct(ring);
print(ring);
}
Output is:
(0,0)(1,0)(0,1)(0,0)
(0,0)(0,1)(1,0)(0,0)
If change from clockwise to counterclockwise then output is:
(0,0)(1,0)(0,1)(0,0)
(0,0)(1,0)(0,1)(0,0)

C++ function throws error when I use a header, but not if I define it in source?

I'm having a weird problem compiling a function when I try using multiple files. I've boiled it down to this simple example: suppose I want to find the sum of a vector of integers. If I try compiling the following code, it works as expected:
#include <vector>
#include <iostream>
using namespace std;
int VectorSum (const vector<int>& values)
{
int S = 0;
for (int t=0; t < values.size(); t++)
{
S += values[t];
}
return S;
}
int main()
{
vector<int> values;
values.push_back(-100);
values.push_back(75);
values.push_back(75);
cout << "Total = " << VectorSum(values) << endl << endl;
cin.ignore(1, '\n');
return 0;
}
However, if I try using a header file, it crashes on my (error C4430 when compiling on VS 2010 for Windows XP). Here's the code for the other approach:
the header:
/* VectorSum.h */
#pragma once
#include <vector>
int VectorSum (const vector<int>& values);
the source:
/* VectorSum.cpp */
#include "VectorSum.h"
#include <vector>
int VectorSum (const vector<int>& values)
{
int S = 0;
for (int t=0; t < values.size(); t++)
{
S += values[t];
}
return S;
}
the implementation:
/* Main.cpp */
#include "VectorSum.h"
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> values;
values.push_back(-100);
values.push_back(75);
values.push_back(75);
cout << "Total = " << VectorSum(values) << endl << endl;
cin.ignore(1, '\n');
return 0;
}
As you can see, the code for the function in VectorSum.cpp is identical to the code in my first .cpp file, so the problem must be in the header. Any ideas what I'm doing wrong?
#pragma once
#include <vector>
int VectorSum (const std::vector<int>& values);
^^^^^
See the MSDN page for C4430. It is issued in case when a declaration is missing a type or the type is unknown. In your case vector is an unknown type due to unqualified name lookup rules.
It's an issue with the std namespace.
Change the declaration in the header to:
int VectorSum (const std::vector<int>& values);
And make sure there's either a using namespace std; in the .cpp file(s) (like your first example) or that you use the std namespace appropriately when calling/defining the function. For example, you'd need to do one of these things in your VectorSum.cpp file.
As an aside, please don't add a
using namespace std;
statement to the header file. That will force the namespace to be brought into scope for all users of the header (even if it's indirectly included, so it might not be obvious), which might not fit their wants or needs.
The problem is indeed in the header file. You forgot to add
using namespace std;
to the header and thus the compiler doesn't know what vector means.
Corrected header:
/* VectorSum.h */
#pragma once
#include <vector>
using namespace std; // This was missing
int VectorSum (const vector<int>& values); // Now OK, the compiler knows vector
You have to specify the namespace for the vector in VectorSum.h:
int VectorSum (const std::vector<int>& values);
Add a using namespace std
/* VectorSum.h */
#pragma once
#include <vector>
<--------
//using namespace std;
int VectorSum (const std::vector<int>& values);
Try to avoid using namespace in header files to avoid name conflicts.