私が次のように書いた場合、void func(const char *str);参照は有効かどうか疑問に思います:str
auto str = string("hello").c_str();
func(str);
以下のコードとどう違うのですか?
func(string("hello").c_str())
どちらの場合も、stringオブジェクトは一時的なものであり、ステートメントの最後で破棄されます。
最初のケースでstrは、ぶら下がってしまいます-一時的に管理されてstringいたが、現在は破棄されているメモリを指しています。それを使って何かをすることはエラーであり、未定義の振る舞いを与えます。
string2番目のケースでは、関数が戻るまで一時は破棄されません。したがって、関数が後で他の何かを使用するためのポインタを保持しない限り、これは問題ありません。
string違いは、最初のステートメントが最初のステートメントの最後で破棄される一時オブジェクトを作成するためstr、ダングリングポインターになることです。func2つ目も一時オブジェクトを作成しますが、一時オブジェクトは呼び出しが戻るまで破棄されないため、呼び出し全体に存在しfuncます。
C ++11標準の12.2/3項から:
[...]一時オブジェクトは、それらが作成されたポイントを(字句的に)含む完全式(1.9)を評価する最後のステップとして破棄されます。これは、その評価が例外のスローで終了した場合でも当てはまります。[...]
これは、toの呼び出しを含む式内に作成された一時的なものが、func()関数呼び出しが戻るまで存続することを意味します。
一方、最初のコードスニペットの一時的な有効期間は、func()呼び出される前に終了し、strぶら下がっています。これにより、未定義の動作が発生します。