据我所知,我不应该被允许在C ++中传递对指针的引用。但是,我这样做的尝试失败了,我不知道为什么。
这就是我正在做的事情:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
我收到了这个错误:
无法将参数1从'std :: string *'转换为'std :: string *&'
答案 0 :(得分:113)
您的函数需要引用调用范围中的实际字符串指针,而不是匿名字符串指针。因此:
string s;
string* _s = &s;
myfunc(_s);
应该编译得很好。
但是,只有在您想要修改传递给函数的指针时,这才有用。如果您打算修改字符串本身,您应该使用Sake建议的字符串引用。考虑到这一点,编译器抱怨原始代码的原因应该更加明显。在你的代码中,指针是“动态”创建的,修改指针没有任何后果,这不是预期的。引用(与指针相对)的想法是引用始终指向实际对象。
答案 1 :(得分:83)
问题在于您尝试将临时绑定到引用,除非引用为const
,否则C ++不允许该引用。
所以你可以做以下其中一项:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
void myfunc2(string* const& val)
{
// Do stuff to the string pointer
}
int main()
// sometime later
{
// ...
string s;
string* ps = &s;
myfunc( ps); // OK because ps is not a temporary
myfunc2( &s); // OK because the parameter is a const&
// ...
return 0;
}
答案 2 :(得分:10)
将其更改为:
std::string s;
std::string* pS = &s;
myfunc(pS);
编辑:
这称为ref-to-pointer
,您不能将临时地址作为函数的引用传递。 (除非它是const reference
)。
虽然,我已经显示std::string* pS = &s;
(指向局部变量的指针),但它的典型用法是:
当您希望被调用者更改指针本身时,而不是它指向的对象。例如,一个分配内存并分配它分配给其参数的内存块地址的函数必须引用指针或指向指针的指针:
void myfunc(string*& val)
{
//val is valid even after function call
val = new std::string("Test");
}
答案 3 :(得分:5)
&s
生成临时指向字符串的指针,你不能引用临时对象。
答案 4 :(得分:3)
尝试:
void myfunc(string& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(s);
// ...
}
或
void myfunc(string* val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
答案 5 :(得分:2)
&s
不是左值,因此您无法创建对它的引用,除非引用的类型是const
的引用。例如,你做不到
string * &r = &s;
但你可以做到
string * const &r = &s;
如果在函数头中添加了类似的声明,它将起作用。
void myfunc(string * const &a) { ... }
还有另一个问题,即临时问题。规则是只有const
时才能获得对临时的引用。因此,在这种情况下,可能会认为& s是临时的,因此必须在函数原型中声明const
。从实际的角度来看,这种情况没有区别。 (无论是左值还是临时值。无论哪种方式,同样的规则都适用。)但是,严格地说,我认为这不是暂时的,而是一个左值。我想知道是否有办法区分这两者。 (或许只是定义所有临时值都是rvalues,所有非左值都是临时值。我不是标准专家。)
话虽如此,你的问题可能处于更高的水平。为什么要引用s
的地址?如果要引用指向s
的指针,则需要在
string *p = &s;
myfunc(p);
如果您想要引用s
或指向s
,请执行简单的操作。
答案 6 :(得分:1)
我刚刚使用了对指针的引用,以便在除了root安全之外的已删除二进制树中生成所有指针。为了使指针安全,我们只需将其设置为0.我无法使删除树的函数(仅保留根)接受指针的引用,因为我使用根(此指针)作为第一个输入到左右移动。
void BinTree::safe_tree(BinTree * &vertex ) {
if ( vertex!=0 ) { // base case
safe_tree(vertex->left); // left subtree.
safe_tree(vertex->right); // right subtree.
// delete vertex; // using this delete causes an error, since they were deleted on the fly using inorder_LVR. If inorder_LVR does not perform delete to the nodes, then, use delete vertex;
vertex=0; // making a safe pointer
}
} // end in
底线,当形参数是(this)指针时,对指针的引用无效。
答案 7 :(得分:0)
欢迎使用C ++ 11和rvalue引用:
#include <cassert>
#include <string>
using std::string;
void myfunc(string*&& val)
{
assert(&val);
assert(val);
assert(val->c_str());
// Do stuff to the string pointer
}
// sometime later
int main () {
// ...
string s;
myfunc(&s);
// ...
}
现在您可以访问指针的值(由val
引用),这是字符串的地址。
你可以修改指针,没人会关心。这是首要问题的一个方面。
注意:指针的值仅在myfunc()
返回之前有效。最后,它是一个临时的。
答案 8 :(得分:-1)
我知道传递指针的引用是可行的,我上周做了,但我不记得语法是什么,因为你的代码现在对我的大脑来说是正确的。然而另一个选择是使用指针指针:
Myfunc(String** s)
答案 9 :(得分:-8)
myfunc(“string *&amp; val”)这本身没有任何意义。 “string *&amp; val”表示“string val”,*和&amp;互相取消。最后一个不能将字符串变量传递给函数(“string val”)。只有基本数据类型可以传递给函数,因为其他数据类型需要作为指针或引用传递。 你可以有字符串&amp; val或string * val到函数。