Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert "this" to a reference-to-pointer

Let's say I have a struct

struct Foo {
    void bar () {
       do_baz(this);
    }
    /* See edit below
    void do_baz(Foo*& pFoo) {
       pFoo->p_sub_foo = new Foo; // for example
    }
    */

    Foo* p_sub_foo;
}

GCC tells me that

temp.cpp: In member function ‘void Foo::bar()’:
temp.cpp:3: error: no matching function for call to ‘Foo::do_baz(Foo* const)’
temp.cpp:5: note: candidates are: void Foo::do_baz(Foo*&)

So, how do I convert what is apparently a const Foo* to a Foo*&?

EDIT: I didn't use a very good example. do_baz should read

void do_baz(Foo*& pFoo) {
    if (pFoo == NULL) {
        pFoo = new Foo;
        return;
    }
    //other stuff
    do_baz(pFoo->p_sub_foo);
    //more stuff
}
like image 838
Austin Hyde Avatar asked Apr 28 '10 00:04

Austin Hyde


1 Answers

You can't.

Firstly, this is not necessarily a const Foo *. this would be a const Foo * is a const method of the class Foo. In a non-const method this is just Foo *. (Actually your error message mentions Foo* const. Where did you see const Foo *?)

Secondly, and more importantly, this is not an lvalue. You can't have a pointer to this. You can't have a non-constant reference to this. The only thing that you can have is a const reverence to this, i.e. a reference of type Foo *const &.

It (Foo *const &) will work in your case.

void do_baz(Foo* const& pFoo) { 
   pFoo->p_sub_foo = new Foo;
} 

But I don't see the point of all this. Just declare a normal Foo * pointer as parameter for your do_baz method

void do_baz(Foo* pFoo) { 
   pFoo->p_sub_foo = new Foo;
} 

and get the same result. What do you think you need that reference for?

EDIT: Taking into account your edit, what you are trying to do cannot be done with a single do_baz function, since in the first call you'd potentially (semantically) attempt to modify this, which is impossible (even if the modifying code will never be executed in practice). Whether you want it or not, you can't have a non-const reference to this, even if you don't intend to write anything through it. You'll probably have to implement the very first call with a different function

void do_baz(Foo*& pFoo) { 
  if (pFoo == NULL) { 
    pFoo = new Foo; 
    return; 
  } 
  //other stuff 
  do_baz(pFoo->p_sub_foo); 
  //more stuff 
} 

void do_baz_root(Foo* pFoo) { 
  assert(pFoo != NULL);
  //other stuff 
  do_baz(pFoo->p_sub_foo); 
  //more stuff 
} 

and then make the first call as

void bar() {
  do_baz_root(this);
}
like image 156
AnT Avatar answered Sep 24 '22 23:09

AnT