I receive the following error on declaring a vector of Point in the code shown (see reference to class template instantiation std::vector<Point,std::allocator<Point>> being compiled):
Severity Code Description Project File Line Suppression State
Error C2558 class 'Point': no copy constructor available or copy
constructor is declared 'explicit' AI assignment 1 C:\Program Files
(x86)\Microsoft Visual
Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 671
#include <iostream>
#include<vector>
using namespace std;
int dx, dy, sx, sy;
class Point
{
public:
int x;
int y;
float g;
float h;
Point()
{}
Point(int s, int d)
{
x = s;
y = d;
h = pow(pow(x - dx, 2) + pow(y - dy, 2), 1 / 2);
}
Point(Point &p)
{
x = p.x;
y = p.y;
g = p.g;
h = p.h;
}
bool operator == (Point p)
{
if (p.x == x && p.y == y)
return true;
else
return false;
}
};
class RoutePlaner
{
vector<vector<char>>grid;
int mapsize;
Point start;
Point destination;
int no_of_obstacles;
vector<Point> obstacles;
void generate_random_obstacles(int num)
{
for (int i = 0; i < num; i++)
{
int k = rand() % mapsize;
int j = rand() % mapsize;
Point p(i, j);
grid[j][k] = 'X';
obstacles.push_back(p);
}
}
public:
RoutePlaner(int m, Point s, Point d, int no)
{
mapsize = m;
start = s;
destination = d;
no_of_obstacles = no;
vector<char> vec(mapsize, '.');
for (int i = 0; i < mapsize; i++)
{
grid.push_back(vec);
}
//Setting start and destination
grid[start.x][start.y] = 'S';
grid[destination.x][destination.y] = 'D';
// setting obstacles
generate_random_obstacles(no_of_obstacles);
}
};
int main()
{
}
How should I declare a vector of class objects? How do I resolve the error?
You need your copy constructor for the Point class to conform to what std::vector (and many other aspects of the STL and C++ language) expects: that means its argument should be a const reference:
Point(const Point& p)
{
x = p.x;
y = p.y;
g = p.g;
h = p.h;
}
Although, in your case, as pointed out in the comment by M.M, the compiler-generated copy constructor will do exactly the same job as yours, so you can just omit your 'explicit' version. Furthermore, if you do declare your own copy constructor, you should also declare a destructor and an assignment operator, in order to follow to "Rule of Three." (Or you can 'meet halfway' by explicitly declaring the default copy constructor: Point(const Point& p) = default;.)
Note, also, that you can simplify your operator == function: whenever you have code of the form, if (x) return true; else return false; you should consider using just return (x);, like this:
bool operator == (Point p) {
return (p.x == x && p.y == y);
}
Related
I'm working on visualizing the Mandelbrot set as well as a few other fractals and there's a lot of duplicated code but no code reuse.
One of the functions I am using is below:
/**
* determines whether a pixel lies in the set
* #params x, y - x and y coordinates on R/I axes
* #param c - a complex number
*/
void calculateSet(int x, int y, Complex c) {
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = z^2 + c;
}
// some code using n to color the set
}
This follows the Mandelbrot set:
z_(n+1) = z_n^2 + c
But look at the relevant code for the Burning Ship set:
void calculateSet(int x, int y, Complex c) {
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = abs(z)^2 + c; // ***
}
// follows z_(n+1) = abs(z_1)^2 + c
}
All the code save for the starred line is identical. Right now I have separate classes for Mandelbrot, BurningShip, and a few others with the only difference being that one line.
Is there a way to define this expression and pass to a generalized Set class?
Some pseudocode:
class Set {
// ...
Set(Type expression) {
// ...
// x, y, c initialized
// ...
calculateSet(x, y, c, expression);
}
void calculateSet(int x, int y, Complex c, Type e) {
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = e;
}
}
};
And I can just use Set to describe any kind of set I wish?
Set mandelbrot = Set(Type("z^2 + c"));
Set burningship = Set(Type("abs(z)^2 + c"));
// etc
I could use if/else statements to have just one class, but it's not generalized.
Since you're limited to C++03, you can use a function pointer relatively painlessly.
Complex mandlebrotCompute(Complex z, Complex c) {
return z*z + c;
}
void calculateSet(int x, int y, Complex c, Complex (*func)(Complex, Complex)) {
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = func(z, c);
}
}
It is used like the following:
Complex foo;
calculateSet(1, 2, foo, mandlebrotCompute);
It might help make the code cleaner to use a typedef for the function pointer.
You can make a template, with the function as template argument.
I believe this is the method that provides the most inlining opportunities.
typedef Complex (*Function)(const Complex&, const Complex&);
template<Function fn>
class Set
{
// ...
void calculateSet(int x, int y, Complex c) {
Complex z = c;
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = fn(z, c)
}
// some code...
}
}
Complex mandelbrot_fn(const Complex& z, const Complex& c)
{
return z^2 + c;
}
Complex burning_fn(const Complex& z, const Complex& c)
{
return abs(z)^2 + c;
}
Set<mandelbrot_fn> mandelbrot;
Set<burning_fn> burning_ship;
That is what lambdas are for I guess.
template<typename Lam>
class Set
{
private:
Lam lam;
public:
Set (Lam&& lam) : lam(lam) {}
void calculateSet(int x, int y, Complex c)
{
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = lam(z, c);
}
}
};
You can use this class like this:
auto mandelbrot = Set([](Complex z, Complex c) -> Complex {
return (z*z) + c;
});
auto burningShip = Set([](Complex z, Complex c) -> Complex {
return abs((z*z)) + c;
});
mandelbrot.calculateSet(...);
burningShip .calculateSet(...);
I have declared a class Image with two operator() functions, one for read-only, the other for read-and-write access.
Here an extract:
class Image {
//...
public:
uint16_t operator()(int x, int y) const
{
return data_[x + y*width_]; // read-only at pixle (x,y)
}
uint16_t & operator()(int x, int y)
{
return data_[x + y*width_]; // read/write to pixle (x,y)
}
//...
}
After this, I declared an object of Image in the main() function and wrote to it (which has to work because of the mentioned public Interface operator()), but several compilers only keep recognizing the first operator() function which has only permission to read.
Example of this:
if (count_alive_neighbors(image, i, j) == 3) {
image(i, j) = 255;
}
My thought was that maybe one could overcome this problem by declaring a pointer and by this changing the value. Code for this:
uint16_t* f = &image(i, j);
*f = 255;
On Microsoft Visual Studio 2015 this first worked tested alone outside the if-loop, but inside the just mentioned function it didn't. But it's not a compiler error, I've tested it with Clang, g++ and MinGW.
All are printing out an error message like this:
error: lvalue required as unary '&' operand
uint16_t* f = &(image(i, j));
^
To sum it up, the question is the following: how could one overcome this problem by not focusing on that pointer declarations, what can one do to tell the compiler which version of operator() it has to use? It doesn't recognize it on its own or maybe I'm not recognizing which settings/code one has to change to make the program work.
Thanks in advance.
edit: whole class definition and function
#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <cstdint>
class Image
{
int width_;
int height_;
std::vector<uint16_t> data_;
public:
Image()
: width_(0)
, height_(0)
{}
Image(unsigned int width, unsigned int height)
: width_(width)
, height_(height)
, data_(width*height, uint16_t())
{}
int width() const
{
return width_;
}
int height() const
{
return height_;
}
int size() const
{
return width_*height_;
}
void resize(unsigned int new_width, unsigned int new_height)
{
data_.resize(new_width*new_height, uint16_t());
width_ = new_width;
height_ = new_height;
}
uint16_t operator()(int x, int y) const
{
return data_[x + y*width_];
}
uint16_t & operator()(int x, int y)
{
return data_[x + y*width_];
}
uint16_t get_periodic(int x, int y) const
{
int xres = x % width_;
int yres = y % height_;
return data_[xres + yres*width_];
}
};
int count_alive_neighbors(Image const & image, int x, int y) {
int res = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (image.get_periodic(x + i, y + j) == 255) {
res += 1;
}
}
}
if (image.get_periodic(x, y) == 255) {
res -= 1;
}
}
Image conway_step(Image const & image) {
for (int i = 0; i <= image.width(); i++) {
for (int j = 0; j <= image.height(); j++) {
if (count_alive_neighbors(image, i, j) == 2)
{
}
if (count_alive_neighbors(image, i, j) == 3) {
image(i, j) = 255;
}
if (count_alive_neighbors(image, i, j) < 2) {
image(i, j) = 0;
}
if (count_alive_neighbors(image, i, j) > 3) {
image(i, j) = 255;
}
}
}
}
int main() {
Image img(3, 3); // declaring object
img(3, 3) = 255; /* !ATTENTION! this works, but inside
conway_steps it doesn't */
}
[Based on the comments] conway_step is supposed to make a copy of its argument, modify that copy, and return the copy. Your problem is that you don't make the copy and try to modify the original.
Please change your function signature from
Image conway_step(Image const & image)
to
Image conway_step(Image & const image) //ill formed
or in a better way
Image conway_step(Image & image)
In first case, it is equivalent to const Image & image, so it calls the const qualified operator => image(i, j)=255; => uint16_t=255 => left operand must be l-value error
In second/third case, you declare a const reference to a non const object.
I have an Eigen MatrixXd object, called v, and I am facing some problems when trying to access this matrix content. When I only print the content at the console (as in the code), works just as fine. When I try to use the content, the error shows up:
Assertion failed: (row >= 0 && row < rows() && col >= 0 && col < cols()), function operator(), file /usr/local/Cellar/eigen/3.2.4/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h, line 337.
ChosenPoint ** points = new ChosenPoint*[width];
for (int i = 0; i < width; i++)
{
points[i] = new ChosenPoint[height];
for (int j = 0; j < height; j++)
{
points[i][j].setPoint(i, j, false);
points[i][j].setNumberOfFrames(numberOfFrames);
}
}
Matrix<double, 2, 1> v = (aT * a).inverse() * aT * b;
if (v.rows() == 2 && v.cols() == 1)
{
points[x][y].setFlow(v(0,0), v(1,0), frame);
}
And my ChosenPoint class:
typedef struct point
{
double x;
double y;
bool isValid;
} point;
class ChosenPoint
{
public:
ChosenPoint()
{
}
~ChosenPoint()
{
}
void setNumberOfFrames(int numberOfFrames)
{
this->flow = new point[numberOfFrames];
for (int i = 0; i < numberOfFrames; i++)
{
point f;
f.x = 0.0;
f.y = 0.0;
this->flow[i] = f;
}
}
void setPoint(int x, int y, bool isValid)
{
this->pt.x = (double) x;
this->pt.y = (double) y;
this->pt.isValid = isValid;
}
point getPoint()
{
return this->pt;
}
point* getFlow()
{
return this->flow;
}
void setFlow(double &xFlow, double &yFlow, int &position)
{
this->flow[position].x = xFlow;
this->flow[position].y = yFlow;
}
void updateFlow(int position)
{
this->flow[position].x = 2*this->flow[position].x;
this->flow[position].y = 2*this->flow[position].y;
}
void updateFlow(double xFlow, double yFlow, int position)
{
this->flow[position].x = xFlow;
this->flow[position].y = yFlow;
}
point pt;
point *flow;
};
My fault. The problem was with one of the other matrixes that I was using in the project, and took me a while to figure it out. Unfortunately, Eigen doesn`t seem to be really helpful when this happens:
I had 2 matrixes (A and B). The matrix with problem was A (somehow, some data was not loaded into the matrix). But when i multiplied A and B, it generated a new matrix C with some valid results (all my sanity checks were unuseful). I admit I don`t know a lot of Eigen.
Anyway, hope this is helpful for more people like me.
How can i use the x and y values of lastLoc object in another function like in the following code. I get no errors but when i print the values of lastLoc in the getPosLoc function I get a long number(possibly address):
class solveMaze {
private:
maze maze;
mouse m;
stack<coords> coordStack;
int x;
int y;
int posLocCount = 0;
coords lastLoc;
};
solveMaze::solveMaze() {
x = m.x;
y = m.y;
coords c(x, y);
coords lastLoc(c.x, c.y);
coordStack.push(c);
}
void solveMaze::getPosLoc() {
if((mazeLayout[x][y-1] == 0) && (x != lastLoc.x) && (y-1 != lastLoc.y)) {
posLocCount++;
putUp();
}
this is the coords.h removed irrelevant functions to shorten the code:
class coords {
public:
coords(){};
coords(int, int);
int x;
int y;
friend ostream &operator<<(ostream &output, const coords &c);
bool operator==(coords);
void operator=(const coords &b);
};
coords::coords(int a, int b) {
x = a;
y = b;
}
this is mouse.h:
class mouse {
private:
maze maze;
public:
mouse();
int x;
int y;
};
mouse::mouse() {
for (int i=0; i<12; i++) {
for (int j=0; j<29; j++) {
if (mazeLayout[i][j] == 8){
x = j;
y = i;
}
}
}
}
There are a couple of evident problems:
coords lastLoc(c.x, c.y);
This statement declares and initialize a local variable named lastLoc... it is not referring to the member lastLoc. For that the code needs to be
lastLoc = coords(c.x, c.y);
x = m.x; and y = m.y;
These statements use m that has not been explicitly initialized, how is that class defined?
You should make getters and setters for x and y, because it's better practise. But if you want refer to coord's x or y. You should write:
lastLoc->x
The following code demonstrate simple operator overloading:
Class Position has 3 int field and a method to print them.
class Position
{
private:
int x,y,z;
public:
void print()
{
cout << x << "," << y << "," << z << endl;
}
Position (int a, int b, int c)
: x(4),
y(50),
z(23)
{
x=a;
y=b;
z=c;
}
Position operator+(const Position &other);
Position operator*=(const int &multi);
};
Operators + and *= are overloaded as such:
Position Position::operator+ (const Position &other)
{
x = x + other.x;
y = y + other.y;
z = z + other.z;
return *this;
}
Position Position::operator*= (const int &multi)
{
x = x * multi;
y = y * multi;
z = z * multi;
return *this;
}
The code runs:
int main()
{
Position p5( 1, 2, 3 );
p5.print();
Position p6( 4, 5, 6 );
p6.print();
Position p7 = p5 + p6;
p7.print();
p7 *= 2;
p7.print();
(p7 *= 2) *= 3;
p7.print();
}
The result yielded are:
1,2,3
4,5,6
5,7,9
10,14,18
20,28,36
Question is why won't the last result perform as it should when it is done in nested?
(p7 *= 2) *= 3;
won't work since you're assigning to a temporary, as you return by value in the operator*= function.
For the sub-expression
p7 *= 2
your operator function is called only for its side-effect, as the temporary it returns would be thrown away. To know more about temporaries, read What are C++ temporaries? and Temporary objects - when are they created, how do you recognise them in code?
When you want expression chaining, you've to return by reference like so
Position& Position::operator*= (int multi)
{
x = x * multi;
y = y * multi;
z = z * multi;
return *this;
}
Aside: You don't have to pass built-in types by const reference(const int &multi), non-const copy (int multi) should do fine.