Reputation: 27436
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
}
Upvotes: 5
Views: 5002
Reputation: 95489
Give the variable a name, and then you will have a pointer reference type:
void bar () { Foo* me = this; do_baz(me); }
I should also point out that your do_baz function isn't making use of the fact that its parameter is a reference (you are not assigning to the pointer, itself, only to what is being pointed to by the pointer). Consequently, it really makes more sense to change the type of the parameter to Foo* instead of Foo*&, or to make it a Foo&, in which case you would use dot (.) instead of arrow (->) when dereferencing the parameter's member.
Edit
Your new version of do_baz now makes use of the fact that the parameter is a reference. The solution above (simply using a named pointer) will still work for your new version of the problem. That said, I would advise against what you are doing. It seems you are trying to insert an element at the end of a linked list...
Firstly, I would advise that if you are implementing a linked list that you maintain not only a pointer to the first node in the list, but also a pointer to the last node in the list at all times, so that insertion at the end of the list may be performed in constant-time. If, however, that is not a possibility, I would nevertheless advise you to use an iterative implementation rather than a recursive one as it is cleaner and simpler. It would look like:
Foo* current=this; while (current->next != NULL){ current=current->next; } current->next = new Foo;
Upvotes: 4
Reputation: 320401
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);
}
Upvotes: 7
Reputation: 340188
The keyword this
is not an lvalue so this
can't be assigned to/changed (regardless of whether what it points to is const
or not). In other words, you might be able to change what this
points to, but you can't change the value of this
itself. The C++ standard 9.3.2 "The this
pointer":
In the body of a nonstatic (9.3) member function, the keyword
this
is a non-lvalue expression
Only const references can bind to non-lvalue objects, so you'd need to bind it to a Foo* const&
if you want to bind the this
pointer to a reference.
Change the signature of the function to:
void do_baz(Foo* const& pFoo);
Upvotes: 0
Reputation: 25647
You don't.
this
is a Foo* const
, meaning it is a const
pointer to a non-const
Foo
. Your reference is non-const, so the correct declaration would be a Foo* const &
.
But it doesn't make any sense to do this, so don't.
Upvotes: 0