9

文字列を変更して返す次の 2 つの関数があるとします。

// modify the original string, and for convenience return a reference to it
std::string &modify( std::string &str )
{
    // ...do something here to modify the string...
    return str;
}

// make a copy of the string before modifying it
std::string modify( const std::string &str )
{
    std::string s( str );
    return modify( s ); // could this not call the "const" version again?
}

このコードは GCC g++ を使用して機能しますが、理由/方法がわかりません。2番目の関数が自分自身を呼び出し、スタックが使い果たされるまで制御不能な再帰が発生するのではないかと心配しています。これは動作することが保証されていますか?

4

3 に答える 3

9

オーバーロードされた関数が 2 つあります。

std::string &modify( std::string &str )
std::string modify( const std::string &str )

あなたが渡しているのは const 修飾されていない ですstd::string。したがって、const 修飾されていない引数を取る関数の方が適しています。それが存在しない場合、コンパイラconst 修飾されていない文字列を const 修飾された文字列に変換して呼び出しを行うことができますが、関数のオーバーロードでは、変換を必要としない呼び出しの方が、変換を必要とする呼び出しよりも適しています。

于 2013-05-01T19:48:17.223 に答える
3
return modify( s ); // could this not call the "const" version again?

いいえ、再帰ではありません。パラメータが である他のオーバーロードを呼び出しますstd::string &

これは、式のsstd::string &が他のオーバーロードされた関数のパラメーターの型と一致するためです。

再帰するには、call-site の引数を に変換する必要がありますstd::string const &。しかし、あなたの場合、変換を必要としないオーバーロードが存在するため、この変換は不要です。

于 2013-05-01T19:45:48.440 に答える
1

これは再帰ではなく、オーバーロードです。2 番目の関数を呼び出すと、それに入る引数は定数文字列です。その関数内で、非定数文字列を取る他の関数を呼び出します。あなたがしているのは、文字列の const-ness を取り除くことです。それを行うより良い方法は、const_cast を使用することです。

この他のスタックオーバーフロースレッドにリンクします。

于 2013-05-01T19:52:08.253 に答える