I'm getting this weird error:
error C2663:
'sf::Drawable::SetPosition' : 2
overloads have no legal conversion for
'this' pointer
I think it has something to do with const mismatches but I don't know where, or why.
In the following code I have a vector of shapes and sprites, and when trying to access one of the vectors shapes and calling one of its functions I'm getting the error.
std::vector<sf::Shape> Shapes;
std::vector<sf::Sprite> Sprites;
bool AddShape(sf::Shape& S){
Shapes.push_back(S); return true;
};
bool AddSprite(sf::Sprite& S){
Sprites.push_back(S); return true;
};
private:
virtual void Render(sf::RenderTarget& target) const {
for(unsigned short I; I<Shapes.size(); I++){
Shapes[I].SetPosition(
Shapes[I].GetPosition().x + GetPosition().x,
Shapes[I].GetPosition().y + GetPosition().y);
target.Draw(Shapes[I]);
}
for(unsigned short I; I<Sprites.size(); I++){
target.Draw(Sprites[I]);
}
}
How can I fix this?
Render is declared with a const after the parameters. This means it does not change its object. Which means, that all of the object's member variables are considered constants within Render, as changing their state means changing the containing object. Assuming Shapes is a member variable, and that SetPosition does change the shape (i.e. not declared as const), you cannot call it within a const member function.
So, remove the const from Render and you'll be fine (you fix your logic, in case it must be const).
Related
I am trying to run a simple C++ program. Whenever I run the code I get the same output 'error: passing 'cont Point' as 'this' argument discards qualifiers [-fpermissive]'. The problem seems to be occurring whenever I call the set function. I am still new to C++ and am still trying to get familiar with its functions so I apologize if the answer may seem obvious. Below is the code that is giving me problems:
#include <QTextStream>
#include <QString>
class Point {
public:
Point(int px, int py)
: m_X(px), m_Y(py) {}
void set(int nx, int ny) {
m_X = nx;
m_Y = ny;
}
QString toString() const {
// m_X = 5;
m_Count++;
return QString("[%1,%2]").arg(m_X).arg(m_Y);
}
private:
int m_X, m_Y;
mutable int m_Count;
};
int main() {
QTextStream cout(stdout);
const Point p(1,1);
const Point q(2,2);
p.set(4,4);
cout << p.toString() << endl;
q.set(4,4);
return 0;
}
In C++, you cannot modify an object marked as const, which is a keyword used in C++, a synonym of "non-modifiable", used to tell the compiler that a variable cannot be modified. In your main,
const Point p(1,1);
const Point q(2,2);
p.set(4,4);
q.set(4,4);
the variables p and q are of type const Point but the member function Point::set is not marked const. Since the member function Point::set is not a const member function of class Point, the compiler thinks the function tries to modify the object it is called on (in the statement p.set(4,4); the function set tries to modify p), but this is not allowed since you marked p (and q) to be const, recall, "non-modifiable".
Now, notice that you could mark member function Point::set as const, but that would be nonsensical since you want to modify the variables (in this case p and q). A solution would be to drop the const qualifier from p and q.
You can watch this video to learn about const member functions; you can also watch this video to learn more about member functions in C++.
I have a matrix class that have a set of functions one of them is
Matrix operator++();
the constructor function:
Matrix(int num_rows,int num_col,int initialization,double initializationValue)
{
this->num_rows=num_rows;
this->num_col=num_col;
if((num_rows*num_col)==0){values=NULL;return;}
values = new double*[num_rows];
for(int index_row=0;index_row<num_rows;index_row++)
{
values[index_row]=new double[num_col];
for(int index_col=0;index_col<num_col;index_col++)
{
switch(initialization)
{
case MI_ZEROS: values[index_row][index_col] =0; break;
case MI_ONES: values[index_row][index_col]=1;break;
case MI_EYE: values[index_row][index_col]=(index_row==index_col)? 1:0;break; //I matrix
case MI_RAND: values[index_row][index_col]=(rand()%1000000)/1000000.0;break;
case MI_VALUE: values[index_row][index_col]=initializationValue;break;
}
}
}
}
the add function:
void Matrix::add(Matrix& m)
{
if(num_rows!=m.num_rows||num_col!=m.num_col)
throw("Invalid Matrix dimensions for add operation");
for(int iR=0; iR<num_rows; iR++ )
for(int iC=0; iC<num_col; iC++)
values[iR][iC] += m.values[iR][iC];
}
when i try to define it like this:
Matrix Matrix::operator++()
{
const double d = 1.0;
add(Matrix(num_rows, num_col, MI_VALUE, d));
return *this;
}
i get this error:
matrix.cpp:367:45: error: invalid initialization of non-const reference of type ‘Matrix&’ from an rvalue of type ‘Matrix’
add(Matrix(num_rows, num_col, MI_VALUE, d));
note:initializing argument 1 of ‘void Matrix::add(Matrix&)’
void Matrix::add(Matrix& m)
i don't really understand why i get this and how to fix it, as it happens a lot in many different functions, how can i fix this?
note: i am using ubuntu 16.04 and a g++ compiler.
You didn't include the code of add to the post, but I can see from the error that it has signature void Matrix::add(Matrix& m). Here Matrix& means that the object you pass must be an l-value. Roughly speaking, an object is l-value if it has a name, and a temporary variable doesn't.
You have to change the signature of your add function: its must be add(Matrix a) or add(const Matrix& a). In first case the function receives a copy of the object. In the second case it receives a constant reference, and temporaries can bind to constant references. The latter is preferred because no unnecessary copies are made.
Never pass arguments by reference (without const) if you don't have intention to modify them in your function. Prefer const Type&.
I need a user defined set according to the order I want. But When I wanted to access set members I got error The object has type qualifiers that are nor compatible with member function (I get this error when I place mouse pointer on error line. The error mentioned in title is fromm Error List after build)
typedef struct tagRECT
{
long left;
long top;
long right;
long bottom;
} RECT;
struct LabelRect : public RECT
{
bool isIsolatedFrom(LabelRect* pRect)
{
if (pRect->right < left ||
pRect->left > right ||
pRect->top > bottom ||
pRect->bottom < top)
return true;
return false;
}
};
class CDrawnLabel
{ public:
LabelRect m_LabelRect;
LabelRect* getLabelRect(){ return &m_LabelRect; }
bool operator<(CDrawnLabel & rhs)
{
//This is the set ordering
return getLabelRect()->right < rhs.getLabelRect()->right;
}
}
I have a set like following
typedef std::set<CDrawnLabel> DrawnLabelSet;
DrawnLabelSet m_setDrawnLabel
I got error when I tried to access set members
DrawnLabelSet::iterator itbegin,itend;
LabelRect* pRectSecond;
itbegin=m_setDrawnLabel.begin();
itend=m_setDrawnLabel.end();
pRectSecond=(*itbegin).getLabelRect();// Here I get the error.
The reason you get this error is because keys inside std::set<T> are stored as const T.
So this expression (*itbegin) returns a const CDrawnLabel. Only const member functions can be called from a const object.
You will have to make getLableRect const. Also since const member functions can only return const pointers/references the member should be:
const LabelRect* getLabelRect() const { return &m_LabelRect; }
Not required but it would be a good idea to make your comparator const as well since it's not modifying any data. Another improvement that can be done is instead of taking a reference you should pass a const ref to the comparator.
bool operator<(const CDrawnLabel &rhs) const
{
//This is the set ordering
return getLabelRect()->right < rhs.getLabelRect()->right;
}
The problem here is that std::set<>::iterator is actually a const_iterator so (*itbegin) has the type const CDrawnLabel&. Why is this? Well, if you could change the reference in the set, you could invalidate the ordering. So you need to take the object out of the set, modify it and then put it back in. Or, if you don't want to change it you could define a const function getConstLabelRect()
I'm trying to construct a class for colors in C++,
this is not an homework is just that I'm still struggling with references and const.
--Color.h
class Color{
private:
double r;
double g;
double b;
double a;
public:
//constructor, getters and setters...
Color& operator =(Color& other_color); //(1)
}
--Color.cpp
Color& operator=(Color& other_color){
this->r = other_color.get_r(); //line 41
this->b = other_color.get_b();
//and so on...
return *this;
}
like this it works fine but I heard one has to put a const to avoid that by fault the object will be modified by the assignement operation, so one has to declare the other object as const. Like this:
Color& operator =(Color const& other_color); //(2)
but it gives me this errors:
/Users/../color.cpp:41: error: passing 'const Color' as 'this' argument of 'float Color::get_r()' discards qualifiers
so here is my question...
what is happening here? second what would happen if I don't declare other_color as const? what are the possible errors?
PS.: little bonus question:
I want to pass my variable to the opengl glColor4v(colorx.return_rgba()) returning the array [r,g,b,a] of the class Color. This:
float* Color::return_rgba(){
float rgba[4] = {this->r, this->g, this->b, this->a};
return rgba;
}
won't work because rgba won't be in scope anymore after the return so it will be deleted and my pointer will point to not initialized adresses, damn...
passing 'const Color' as 'this' argument of 'float Color::get_r()' discards qualifiers
This means you have to take it further. get_r is probably declared as
float get_r()
and to make it work (const-correctly), you should make it
float get_r() const
second what would happen if I don't declare other_color as const?
You would be unable to assign from const-qualified Colors. You usually want to be able to use const objects, among other as source of assignment. Moreover, it makes the intent not to modify the source clear to the reader of the code.
I want to pass my variable to the opengl glColor4v(colorx.return_rgba()) returning the array [r,g,b,a] of the class Color.
Return a special "vehicle" that would contain the array and convert automatically to float*. Something along
struct ColorQuadruplet
{
float data_[4];
// add initialization and such here
operator float*() { return data_; }
};
ColorQuadruplet Color::get_rgba() const
{
ColorQuadruplet ret;
// fill ret
return ret;
}
You have two choices here. One is for your operator= to directly access to the members of the source object:
Color &operator=(Color const &other) {
r = other.r;
g = other.g;
b = other.b;
a = other.a;
}
The other (which you probably want to do in any case, if you insist on having accessors for the color components at all) is to const-qualify the accessors you've written:
double get_r() const { return r; }
^^^^^
The const here is the part I've added that you apparently don't have.
Edit: as far as passing the values to glColor goes, I'd consider a small front-end something like this:
gl_color(Color const &c) {
glColor4d(c.r, c.g, c.b, c.a);
}
I'm having some trouble compiling my code - it has to do with the types I'm passing in. Here is what the compiler says:
R3Mesh.cpp: In copy constructor 'R3Mesh::R3Mesh(const R3Mesh&)':
R3Mesh.cpp:79: error: no matching function for call to 'R3Mesh::CreateHalfEdge(R3MeshVertex*&, R3MeshFace*&, R3MeshHalfEdge*&, R3MeshHalfEdge*&)'
R3Mesh.h:178: note: candidates are: R3MeshHalfEdge* R3Mesh::CreateHalfEdge(const R3MeshVertex*&, const R3MeshFace*&, const R3MeshHalfEdge*&, const R3MeshHalfEdge*&)
R3Mesh.cpp: In constructor 'R3MeshHalfEdge::R3MeshHalfEdge(const R3MeshVertex*&, const R3MeshFace*&, const R3MeshHalfEdge*&, const R3MeshHalfEdge*&)':
R3Mesh.cpp:1477: error: invalid conversion from 'const R3MeshVertex*' to 'R3MeshVertex*'
R3Mesh.cpp:1477: error: invalid conversion from 'const R3MeshFace*' to 'R3MeshFace*'
R3Mesh.cpp:1477: error: invalid conversion from 'const R3MeshHalfEdge*' to 'R3MeshHalfEdge*'
R3Mesh.cpp:1477: error: invalid conversion from 'const R3MeshHalfEdge*' to 'R3MeshHalfEdge*'
Here is how I define my R3MeshHalfEdge:
struct R3MeshHalfEdge {
// Constructors
R3MeshHalfEdge(void);
R3MeshHalfEdge(const R3MeshHalfEdge& half_edge);
R3MeshHalfEdge(const R3MeshVertex*& vertex, const R3MeshFace*& face,
const R3MeshHalfEdge*& opposite, const R3MeshHalfEdge*& next);
R3MeshVertex *vertex;
R3MeshFace *face;
R3MeshHalfEdge *opposite;
R3MeshHalfEdge *next;
int id;
};
This is what the first error complains about:
R3MeshHalfEdge *R3Mesh::
CreateHalfEdge(const R3MeshVertex*& vertex, const R3MeshFace*& face,
const R3MeshHalfEdge*& opposite, const R3MeshHalfEdge*& next)
{
// Create half_edge
R3MeshHalfEdge *half_edge = new R3MeshHalfEdge(vertex, face, opposite, next);
// Set half_edge ID
half_edge->id = half_edges.size();
// Add to list
half_edges.push_back(half_edge);
// Return half_edge
return half_edge;
}
This is what the second error complains about:
R3MeshHalfEdge::
R3MeshHalfEdge(const R3MeshVertex*& vertex, const R3MeshFace*& face,
const R3MeshHalfEdge*& opposite, const R3MeshHalfEdge*& next)
: vertex(vertex),
face(face),
opposite(opposite),
next(next),
id(0)
{
}
Here is where I call the CreateHalfEdge function:
for(int i=0; i<mesh.NFaces(); i++)
{
R3MeshFace *f = mesh.Face(i);
vector<R3MeshVertex *> face_vertices; // assume vertices are stored in order around the perimeter of the face
for(unsigned int j = 0; j<f->vertices.size(); j++)
{
R3MeshVertex *v1 = f->vertices[j];
R3MeshVertex *v2;
if(j==f->vertices.size()-1)
v2 = f->vertices[0];
else
v2 = f->vertices[j+1];
int v1_id = v1->id;
int v2_id = v2->id;
R3MeshHalfEdge *next = NULL;
R3MeshHalfEdge *opposite = NULL;
R3MeshHalfEdge *half_edge = CreateHalfEdge(v1, f, opposite, next);
}
... }
The constructor is wrong:
R3MeshHalfEdge(const R3MeshVertex*& vertex, const R3MeshFace*& face,
const R3MeshHalfEdge*& opposite, const R3MeshHalfEdge*& next);
You pass pointers to const and assign them to pointers to non-const, which fails.
Correct it like so:
R3MeshHalfEdge(R3MeshVertex* vertex, R3MeshFace* face,
R3MeshHalfEdge* opposite, R3MeshHalfEdge* next);
As a remark:
there are two level of const with pointers: pointers to const (const X*) and const pointers (X* const) the former can point to something else but cannot change the object pointed to while the latter cannot be rebound to another object but can change the object pointed. You can combine them to have a const pointer to const (const X* const)
don't pass pointers by reference (*&) unless you intend to modify the pointer itself, and not the object pointed.
Saying const type *¶meter means that you can modify parameter:
void foo(const int *¶meter)
{
int bar= 0;
parameter= &bar;
}
I suspect you don't want to do that. Instead of passing pointers by reference, either pass them by value (since you aren't modifying them) or pass them by const reference (const type * const ¶meter).
You're passing non-const pointers to a function that expects const pointer arguments, it seems.
Note:
...But this shouldn't be a problem. I suspect there's something else going on here, but the question is missing some information. The compiler error is about something in the copy constructor R3Mesh::R3Mesh(const R3Mesh&), which isn't shown in the question.
Edit: OK, it is shown now. I would suggest clearing up the const reference to pointer issues first, and seeing what's left.
The second error is pretty clear, actually - either the arguments to the R3MeshHalfEdge constructor shouldn't be references to const pointers (which tell the compiler you don't intend to change the objects they point to) or the data members you assign those arguments to should be const pointers themselves.
You need to look at your argument and reevaluate what should be constant and what shouldn't.
Your compiler error is thrown because you are pointing a nonconstant pointer (vertex, for example) at constant memory (the vertex argument). In C++ constant and nonconstant variables are different types.
Read through this for a lot more detail.
If you just want it to work, remove all your consts and it will compile. If you want your arguments to be constant, you'll have to do copy copying and assignments of data (not pointers!) to remove the error.
Also, rename your arguments so that you don't have name collisions with your member variables.