假设我有一个结构
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告诉我
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*&)
那么,如何将显然为const Foo*
的内容转换为Foo*&
?
编辑:我没有使用一个很好的例子。 do_baz
应该阅读
void do_baz(Foo*& pFoo) {
if (pFoo == NULL) {
pFoo = new Foo;
return;
}
//other stuff
do_baz(pFoo->p_sub_foo);
//more stuff
}
答案 0 :(得分:7)
你做不到。
首先,this
不一定是const Foo *
。 this
是const Foo *
是类Foo
的const方法。在非const方法中,this
只是Foo *
。 (实际上您的错误消息提到Foo* const
。您在哪里看到const Foo *
?)
其次,更重要的是,this
不是左值。你不能指向this
。您不能对this
进行非常量引用。你唯一可以拥有的是对this
的崇敬,即对Foo *const &
类型的引用。
它(Foo *const &
)将适用于您的情况。
void do_baz(Foo* const& pFoo) {
pFoo->p_sub_foo = new Foo;
}
但我没有看到这一切的重点。只需声明一个普通的Foo *
指针作为do_baz
方法的参数
void do_baz(Foo* pFoo) {
pFoo->p_sub_foo = new Foo;
}
得到相同的结果。你认为你需要什么参考?
编辑:考虑到您的编辑,使用单个do_baz
功能无法完成您要执行的操作,因为在第一次调用中您可能(语义上)尝试修改this
,这是不可能的(即使修改代码永远不会在实践中执行)。无论你是否想要它,你都不能拥有this
的非const引用,即使你不打算通过它写任何东西。您可能必须使用不同的函数实现第一个调用
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
}
然后以
进行第一次通话void bar() {
do_baz_root(this);
}
答案 1 :(得分:4)
为变量命名,然后您将有一个指针引用类型:
void bar () { Foo* me = this; do_baz(me); }
我还应该指出你的do_baz函数没有利用它的参数是一个引用的事实(你不是指向指针本身,只指向指针指向的指针)。因此,将参数的类型更改为Foo *而不是Foo *&或将其设置为Foo&更为有意义,在这种情况下,您将使用点(。)而不是箭头( - >)取消引用参数的成员时。
修改的
您的新版do_baz现在使用参数是参考的事实。上面的解决方案(只使用命名指针)仍然适用于您的新版本的问题。那就是说,我会反对你在做什么。您似乎正在尝试在链接列表的末尾插入元素...
首先,我建议如果你实现的是一个链表,你不仅要保存指向列表中第一个节点的指针,还要指向列表中最后一个节点的指针,以便插入列表的末尾可以在恒定时间内执行。但是,如果这不可能,我会建议您使用迭代实现而不是递归实现,因为它更简洁。它看起来像是:
Foo* current=this; while (current->next != NULL){ current=current->next; } current->next = new Foo;
答案 2 :(得分:0)
关键字this
不是左值,因此this
无法分配/更改(无论它指向的是const
还是this
)。换句话说,您可以更改this
指向的内容,但不能更改this
本身的值。 C ++标准9.3.2“this
指针”:
在非静态(9.3)成员函数的主体中,关键字
Foo* const&
是非左值表达式
只有const引用可以绑定到非左值对象,因此如果要将this
指针绑定到引用,则需要将其绑定到void do_baz(Foo* const& pFoo);
。
将功能的签名更改为:
{{1}}
答案 3 :(得分:0)
你没有。
this
是Foo* const
,这意味着它是指向非const
const
的{{1}}指针。您的引用是非const的,因此正确的声明将是Foo
。
但这样做没有任何意义,所以不要。