私が知る限り、C++のポインターへの参照を渡すことを許可されない理由はありません。しかし、そうしようとする試みは失敗しており、その理由はわかりません。
これは私がやっていることです:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
そして、私はこのエラーを受け取っています:
パラメーター1を「std :: string *」から「std :: string *&」に変換できません
関数は、匿名の文字列ポインターではなく、呼び出しスコープ内の実際の文字列ポインターへの参照を想定しています。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example:
string s;
string* _s = &s;
myfunc(_s);
うまくコンパイルできるはずです。
ただし、これは、関数に渡すポインターを変更する場合にのみ役立ちます。文字列自体を変更する場合は、Sakeが提案した文字列への参照を使用する必要があります。それを念頭に置いて、コンパイラが元のコードについて文句を言う理由がより明確になるはずです。あなたのコードでは、ポインターは「オンザフライ」で作成され、そのポインターを変更しても結果はなく、それは意図したものではありません。参照の概念(対)は、参照が常に実際のオブジェクトを指すというものです。
問題は、参照に一時をバインドしようとしていることです。参照が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;
}
次のように変更します。
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");
}
&s
は文字列への一時的なポインタを生成し、一時的なオブジェクトへの参照を作成できません。
試してください:
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
と宣言する必要があると主張するかもしれません。実用的な観点からは、この場合には違いはありません。 (これは右辺値または一時値のいずれかです。いずれにしても、同じ規則が適用されます。)ただし、厳密に言えば、一時値ではなく右辺値だと思います。この2つを区別する方法はあるのでしょうか。 (おそらく、すべての一時値は右辺値であり、すべての非左辺値は一時値であると単純に定義されています。私は標準の専門家ではありません。)
そうは言っても、あなたの問題はおそらくより高いレベルにあります。 s
のアドレスへの参照が必要な理由s
へのポインターへの参照が必要な場合は、次のようにポインターを定義する必要があります。
string *p = &s;
myfunc(p);
s
への参照またはs
へのポインターが必要な場合は、簡単なことをしてください。
ポインターへの参照を使用して、ルートセーフ以外の削除されたバイナリツリー内のすべてのポインターを作成しました。ポインタを安全にするには、0に設定するだけです。ルート(このポインタ)を最初に使用しているため、ツリーを削除する(ルートのみを保持する)関数を作成してポインタへのrefを受け入れることができませんでした左右に移動するための入力。
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()
が戻るまで有効です。最後に、それは一時的なものです。