C++ types and functions - c++

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 *&parameter means that you can modify parameter:
void foo(const int *&parameter)
{
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 &parameter).

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.

Related

Non const field fine in a function but recognised as const in another one

I have a non const field ctxt.
And I have a funtion like this:
inventory_input inventory_selector::get_input()
{
inventory_input res;
const input_context ip;
res.action = ctxt.handle_input();
res.ch = ctxt.get_raw_input().get_first_input();
std::tuple<point, bool> tuple = ctxt.get_coordinates_inventory( w_inv );//Fine
std::tuple<point, bool> tuple = ip.get_coordinates_inventory( w_inv );//Error
res.entry = find_entry_by_invlet( res.ch );
if( res.entry != nullptr && !res.entry->is_selectable() ) {
res.entry = nullptr;
}
return res;
}
the error is "the object has type qualifiers that are not compatible with the member function" as ip is const but the funtion get_coordinates_inventory is not const.
However, I have a nother funtion like this:
inventory_entry *inventory_selector::find_entry_by_coordinate( point coordinate ) const
{
input_context ip;
std::tuple<point, bool> tuple = ctxt.get_coordinates_inventory( w_inv );//surprising, this line is having error.
std::tuple<point, bool> tuple = ip.get_coordinates_inventory( w_inv );//this line dosn't has error
}
The error message is:
the object has type qualifiers that are not compatible with the member function "input_context_inventory" object type is: const input_context.
I cannot understand why is this happening, both ctxt and ip are non const how can one of them having error while another one doesn't?
I have a non const field ctxt
...
the funtion get_coordinates_inventory is not const
There is your problem. Note the const qualifier on this method:
inventory_entry *inventory_selector::find_entry_by_coordinate( point coordinate ) const
^^^^^
This means that this method can be invoked on a const inventory_selector. Therefore, within this function the implicit this pointer points to const inventory_selector. Because of this, you can't invoke a non-const method on ctxt -- it is also const since it is a member of an object that is considered const within the context of the method:
this is const inventory_selector *.
So this->ctxt is const input_context &.
So the invocation this->ctxt.get_coordinates_inventory() is disallowed because that method is not declared const.
Either inventory_selector::find_entry_by_coordinate should be made non-const, or input_context::get_coordinates_inventory should be made const.

occur no matching function for call to error in c++

I'm a novice in c++, i know there is a lot of similar questions but unfortunately didn't help me to solve this problem (which is a conceptual misunderstood i think)
So i have this constructor
Field::Field(const Position &posG, const Position &posC) {
//...
}
And i am creating a Field as follows
// Create positions
Position posG, posC;
posG.x = 3;
posG.y = 3;
posC.x = 4;
posC.y = 4;
// Create pointers to positions
const Position *pPosC(&posC);
const Position *pPosG(&posG);
// Create field
Field field (pPosG, pPosC);
Where position is
struct Position {
int x;
int y;
};
Then i am getting this exception:
main.cpp:27:30: error: no matching function for call to ‘Field::Field(const Position*&, const Position*&)’
Field Field (pPosG, pPosC);
In file included from main.cpp:2:0:
Any help? Regards
Field(const Position &posG, const Position &posC);
^^^^^ ^^^^^^
Those are references. So when you try to pass pointers
Field field (pPosG, pPosC);
^^^^^ ^^^^
pointer pointer
It can't compile.
Either make the constructor accept reference pointers (const Position *&posG) or pass the value of the pointers (*pPosG), or just pass the values directly (posG).
When you have a constructor defined as
Field(const Position &posG, const Posicion &posC);
You can use objects of type Position as arguments to it, not pointers to Position.
You can use:
Field field(posG, posC);
or
Field field(*pPosG, *pPosC);
Your constructor expects references, not pointers.
As a sidenote, it's not clear why you use references or pointers.
you must define a constructor, then use of const Position *pPosC(&posC); expression.
you must define constructor-copy like this :
struct Posicion {
public :
Position(const Position &pos) // constructor copy
{
// some code here
x = pos.x;
y = pos.y;
}
int x;
int y;
};

Passing ifstream not recognized

I'm getting this error message
error: no matching function for call to
HCTree::build(std::basic_ifstream < char, std::char_trait< char>> &)
const
note: candidates are: HCNode* HCTree::build(std::ifstream&) < near
match>
in .cpp
int HCTree::decode(ifstream &in) const {
if(root == NULL) {
root = build(in); <-- error here
}
return aux_decode(in, root); <-- similarly error here too
}
in .hpp
HCNode* build(ifstream &in);
I don't quit understand what am I doing wrong
This looks like a constness problem.
Just a wild guess, but does your HCTree class inherit from HCNode?
You're trying to call a non-const member function from a const function, which is illegal. Furthermore, assuming root is a non-mutable member variable of the HCTree or HCNode class, trying to modify it in the const decode function is also illegal. Try removing the const qualifier from HCTree::decode, since it seems not to be const at all.
Alternatively, if root is not a non-mutable member variable, you could declare HCNode::build as const, assuming it actually doesn't mutate any state.

Operator overload = and const reference

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);
}

Const mismatches: 2 overloads have no legal conversion for 'this' pointer

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).