回答:
関数は、匿名の文字列ポインターではなく、呼び出しスコープ内の実際の文字列ポインターへの参照を期待しています。したがって:
string s;
string* _s = &s;
myfunc(_s);
うまくコンパイルできるはずです。
ただし、これは、関数に渡すポインターを変更する場合にのみ役立ちます。文字列自体を変更するつもりなら、酒が提案したように文字列への参照を使用する必要があります。これを念頭に置くと、コンパイラが元のコードについて文句を言う理由がより明確になるはずです。あなたのコードでは、ポインターは「オンザフライ」で作成され、そのポインターを変更しても何の影響もなく、それは意図されたものではありません。参照(対ポインター)の考え方は、参照は常に実際のオブジェクトを指すということです。
問題は、一時変数を参照にバインドしようとしていることです。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 'よりも明確reference to an actual string pointer in the calling scope, not an anonymous string pointer
です。とにかく、どちらも私の見解では正しいと思われます。
const string*&
そしてstring* const&
実際には異なる種類があります。1つ目はへの非const
参照const string*
ですが、2つ目はへの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
で、文字列のアドレスであるポインタ(によって参照される)の値にアクセスできます。
ポインタを変更することができ、誰も気にしません。これは、そもそも右辺値が何であるかの1つの側面です。
注意:ポインターの値は、myfunc()
戻るまでのみ有効です。ついに、それは一時的なものです。
string* const& val
有益const string* &val
です。たとえば、のような判読しにくい同等のものではありません。私の目には、これは明らかに、const 参照、ポインタ、文字列への参照です。私は個人的T const&
にはconst T&
、この正確な説明を得るために、宣言ではなく書くことを好みます。