2010-11-23 17 views
0

私は、明示的な、しかし安全なキャストを行うことができるように定義された次のテンプレートを持っている:安全な変換* - 一時的な寿命の問題

/// cast using implicit conversions only 
template <class To,class From> 
inline To safe_cast(const From &from) {return from;} 

よく(例えばsprintfのと同様の機能に引数を渡します)このテンプレートを使用して、文字列クラスからCスタイルの文字列への変換を実行したいと思います。しかし、これは一時的なものが渡された場合には不可能であることを示しています。

次の例を検討:obj.GetDebugName(から一時

class Object 
{ 
    public: 
    MyStringClass GetDebugName() const; 
}; 

Object obj; 
printf("%s",safe_cast<const char *>(obj.GetDebugName())); 

)をsafe_cast中のみ住ん及びポインタときに内部(既に破壊された一時的な文字列のデータの点)が無効ですprintfの。

回避策として、テンプレート呼び出しなしで現在現在使用しているダイレクトキャスト:const char *c = (const char *)(obj.GetDebugName()がありますが、キャストは不必要に強いので、型の安全性が低下するという欠点があります(obj.GetDebugName()文字列値の代わりにintを返す)。 static_castはやや良いかもしれませんが、それでも強すぎると、キャストが安全でないと思われる状況ではエラーが発生します。

1)私が間違っていないとすれば、標準では一時的なライフタイムがステートメントであると言われています(const参照にバインドされている場合を除き、参照の寿命です)。上記のprintfの例を見ると、私は "文"が何であるか、そして私が見た振る舞いが合致しているかどうかは分かりません。ステートメントがprintf全体の場合は、&からのconstの有効期間は短くなります。一時的なものからどのような生涯が期待できますか?誰かが明確にすることはできますか?

2)他にも安全な変換を行う方法はありますか?その結果は有効になるほど長く生き続けますか?

編集:

してください、一般的な質問の種類この多くを検討し、私はこのような変換は、一時的な寿命に関して行うことにすることができる方法のメカニズムのために求めている、私はそれほど興味がありません特定の文字列クラスの特別な場合。

.c_strなどのメンバー関数を使用しない理由を明確にするために、変換コードを型に依存しないようにしたいと思います。この特定の文字列型が知っていることをコードに依存させたくありません。 c_strが実装されている場合、ObjectDebugNameによって別の文字列クラスが返された場合でも、ObjectDebugNameがすでにconst char *を返す場合であっても動作するようにします(.operator const char *()を呼び出す可能性は排除します)。

+0

何もせずに、もし私が聞くことができます。 –

+0

const char * c =(const char *)(obj.GetDebugName())はどうやってやるの? MyStringClassの中にいくつかの "演算子char *"がありますか? – cybevnm

+1

私は誤っているかもしれませんが、式で作成された一時的なものは、式全体の終わり(printfの呼び出し終了)まで生きていませんか? – visitor

答えて

2

を私は明示的に行う暗黙のキャストを呼び出し、または単に明示的な考え明示的な、しかし安全なキャスト

を行うことができます暗黙のキャスト

1)私は間違っていないよ場合は、標準では、それは、参照の寿命であり、その場合にはconst参照にバインドされることによって拡張されない限り、一時的な寿命は)(文ですと言います。上記のprintfの例を見ると、私は "文"が何であるか、そして私が見た振る舞いが合致しているかどうかは分かりません。ステートメントがprintf全体の場合は、&からのconstの有効期間は短くなります。一時的なものからどのような生涯が期待できますか?誰かが明確にすることはできますか? printf'veが返された後

あなたは正しいですが、一時的に破壊されます。 あなたが提供したコードはうまくいくはずです。そうでない場合は、重要な情報を誤って提示したことを意味します。

+0

safe_castと一時的な生存期間がまだ問題を引き起こしているかどうか再度確認します。今すぐアーカイブを閲覧し、2004年、つまりVisual Studio 2005の前に一時的な生存期間の問題があることを示しています。 – Suma

+0

Visual Studio 2005では、コードは正常に動作します。 – Suma

1

私はここであなた自身の文字列クラスを使用しているのか分かりません。クラスにはconst char *を取得するメンバ関数がありますか?

std :: string GetDebugName();

printf( "%s"、GetDebugName()。c_str());

は、テンポラリがそのステートメント中に有効なままであるので安全です。

0

あなたは、直接変換関数を呼び出すことができます。

printf("%s", obj.GetDebugName().operator const char*()); 
+0

'static_cast (obj.GetDebugName())'のようにも見えるかもしれません。なぜ 'safe_cast'関数が必要なのでしょうか? – UncleBens

+0

@UncleBens:提案された 'safe_cast (From&const)'テンプレートは、To :: To(From const&) 'も考慮に入れます。私が書いた直接呼び出しは、一般的に無害な恒常的なオーバーロードの対象です。 – MSalters