views:

143

answers:

4

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

        }

... }
+2  A: 

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.

Ori Pessach
Can I un-const them somehow? The reason I was doing this is because I was provided with a skeleton code that had functions Vertex() and Face() with similar structures, meaning that the constructors expected const variables and when I looked at the way they were created using the new operator, I followed the example. They didn't do anything special with their variables - pretty much what I included, I think
Myx
You cannot un-const a constant. You can copy the memory out with assignments or memory copies.
thebretness
Anyway, you can pass non-const pointers to a function that expects const pointer arguments. That wouldn't cause a compilation error.
thebretness
Matthieu M.
I thought that I can pass non-const pointers to a function that expects const pointer arguments. So then something else must be causing the compilation error? (although I just tried changing the variables that I pass into the function to const and it compiles)
Myx
this is the eaxact opposit of what he is doing. he is trying to pass const pointers to a function that expects non-const, casting away the const would be dangerous if the function modifies the variable, but might be the solution for interfacing with a legacy api
jk
Ori Pessach
Myx
Those parameters aren't const references; they are references to const pointers, which means they **can** be modified.
MSN
@MSN: You're right. Ugh.
Ori Pessach
+1  A: 

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.

thebretness
+2  A: 

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.
Matthieu M.
So what I wish to do is have a HalfEdge which points to a Vertex, Face, opposite HalfEdge, and next HalfEdge. I should also be able to change the opposite and next pointers somewhere else in the program by doing something like myEdge->next = yourEdge. Should I still use your correction?
Myx
A more correct way to fix this would probably be to remove the references rather than to remove both the consts and the references.
Dan Olson
I changed my constructor and related function to accept non-const types after considering exactly what it was I was trying to do. Firstly, the 'opposite' and 'next' variables didn't need to exist in the constructor since I never explicitly set them in the constructor but rather modify them later on in the code. The 'vertex' and 'face' arguments could also change, so I just made those as R3MeshVertex* vertex and R3MeshFace* face and it did the job.
Myx
@Dan: given that the attributes are pointer to non-const, I supposed that the OP wanted to actually modify the objects passed. Granted it was a guess.
Matthieu M.
+2  A: 

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

MSN
+1: Technically the pointers might be getting modified if the members they are being assigned to are also references to pointers. I suspect not though. :)
Troubadour