Answers:
问题在于您正在尝试将临时绑定到引用,除非引用为,否则C ++不允许const
。
因此,您可以执行以下任一操作:
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;
}
bind a temporary to the reference
此答案中的短语比@Chris'as更清晰reference to an actual string pointer in the calling scope, not an anonymous string pointer
。无论如何,从我的角度来看,两者都可能是正确的。
const string*&
而且string* const&
实际上是不同的类型。第一个是对a的不const
引用const string*
,而第二个是对a的const
引用string*
。
T const&
来const T&
-作为@Justin时指出,他们是不同类型的。它可能没有结果的时候,但是在其他情况下,这将是绝对关键的喜欢一个或另一个,就像喜欢int
到double
。
更改为:
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");
}
尝试:
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);
// ...
}
编辑:我做了一些实验,发现事情比我想象的要微妙。我现在认为这是一个准确的答案。
&s
不是左值,因此除非引用的类型为,否则您无法创建对其的引用const
。因此,例如,您不能
string * &r = &s;
但是你可以做
string * const &r = &s;
如果在函数头中放置类似的声明,它将起作用。
void myfunc(string * const &a) { ... }
还有另一个问题,即临时工。规则是,只有在临时目录下,您才能获得对它的引用const
。因此,在这种情况下,可能会说&s是临时的,因此必须声明const
在函数原型中。从实际的角度来看,在这种情况下没有区别。(它可以是一个右值,也可以是一个临时值。无论哪种方式,都适用相同的规则。)但是,严格来说,我认为这不是一个临时值,而是一个右值。我想知道是否有办法区分两者。(也许只是简单地定义了所有临时变量都是右值,而所有非左值都是临时值。我不是标准专家。)
话虽如此,您的问题可能在更高的层次上。为什么要引用地址s
?如果要引用指向的指针s
,则需要定义一个指针,如下所示:
string *p = &s;
myfunc(p);
如果您要引用s
或指向s
,请做直接的事情。
我刚刚利用了对指针的引用来使已删除的二叉树中除根安全以外的所有指针都安全。为了使指针安全,我们只需要将其设置为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)指针时,对指针的引用无效。
欢迎使用C ++ 11和右值引用:
#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()
返回之前有效。最后,这是暂时的。
myfunc(“ string *&val”)这本身没有任何意义。“ string *&val”表示“ string val”,*和&相互抵消。最后,不能将字符串变量传递给函数(“字符串val”)。只能将基本数据类型传递给函数,因为其他数据类型需要作为指针或引用传递。您可以对函数使用string&val或string * val。
string* const& val
而不是像例如const string* &val
。在我看来,这显然是对字符串的const 引用,指针。我个人更喜欢用书面形式T const&
而不是const T&
声明形式来获得确切的说明。