私の質問は、stringstream.str().c_str()
から返された文字列はどこにありますか?そしてそれはなぜconst char*
に割り当てられないのですか?stringstream、string、char *変換の混乱
このコード例では、私が
でき#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringstream ss("this is a string\n");
string str(ss.str());
const char* cstr1 = str.c_str();
const char* cstr2 = ss.str().c_str();
cout << cstr1 // Prints correctly
<< cstr2; // ERROR, prints out garbage
system("PAUSE");
return 0;
}
より良いstringstream.str().c_str()
を追跡するために私にしばらく時間がかかったバグにつながっconst char*
に割り当てることができることを前提にそれを説明します。
cout << cstr // Prints correctly
<< ss.str().c_str() // Prints correctly
<< cstr2; // Prints correctly (???)
が正しく文字列を印刷してcout
文を交換する理由ボーナスポイント
は、誰もが説明できますか?
私は、Visual Studioでコンパイルしています2008年
'str()'がRVOが実行されるように実装されていると(おそらくそうです)、コピーを実行すると(最初の例のように)オーバーヘッドが必ずしも発生しないことに注意してください。コンパイラは結果を 'tmp'に直接組み込み、一時的なものを取り除くことができます。最新のC++コンパイラは、最適化が有効になっているときにこれを行います。もちろん、バインド・ツー・コンスタント・リファレンス・ソリューションはコピーを保証しないので、望ましいかもしれませんが、それでも明らかにする価値はあると思いました。 –
"もちろん、バインド・ツー・コンスタント・リファレンス・ソリューションはコピーを保証しません。 C++ 03では、コピーコンストラクタにアクセス可能である必要があり、実装で初期化子をコピーして参照をコピーにバインドすることができます。 –
あなたの最初の例は間違っています。 c_str()によって返される値は一時的です。現在のステートメントの終了後には信頼できません。したがって、それを使って関数に値を渡すことはできますが、c_str()の結果をローカル変数に割り当ててはいけません。 –