明示的で安全なキャストを実行できるように、次のテンプレートを定義しています。
/// cast using implicit conversions only
template <class To,class From>
inline To safe_cast( const From &from ) {return from;}
頻繁に (たとえば、sprintf や同様の関数に引数を渡す場合)、このテンプレートを使用して、文字列クラスから C スタイルの文字列への変換を実行したいと考えています。ただし、一時的なものは十分に長く存続しないため、一時的なものを渡すとこれが不可能であることを示しています。
次の例を検討してください。
class Object
{
public:
MyStringClass GetDebugName() const;
};
Object obj;
printf("%s",safe_cast<const char *>(obj.GetDebugName()));
obj.GetDebugName() からのテンポラリは、safe_cast の間だけ存続し、ポインタは、printf の内部では無効です (すでに破棄されている文字列テンポラリのデータを指します)。
回避策として、私は現在、テンプレート呼び出しなしで直接キャストを使用しています: const char *c = (const char *)(obj.GetDebugName()
、ただし、キャストが不必要に強力であるため、型の安全性が低下するという欠点があります (たとえば、obj.GetDebugName() が代わりに int を返す場合でも、暗黙のうちに成功します)。文字列値)。static_cast
少し良いかもしれませんが、それでも強すぎるので、キャストが安全であると確信できない状況ではエラーを取得したいと思います.
1)私が間違っていなければ、標準は一時的なライフタイムはステートメントであると言います(const参照にバインドされて拡張されない限り、その場合は参照のライフタイムです)。上記のprintfの例を見ると、「ステートメント」とは何か、また、見た動作が適合しているかどうかがよくわかりません。ステートメントが printf 全体である場合、const From &from の有効期間は短くなります - 一時的な有効期間はどのくらいですか? 誰かが明確にすることができますか?
2)安全な変換を行う他の方法はありますが、結果は有用なほど長く存続しますか?
編集:
これは一種の一般的な質問だと考えてください。一時的な有効期間に関してこのような変換を行う方法を探しています。特定の文字列クラスの特殊なケースにはあまり興味がありません。
.c_str または同様のメンバー関数を使用したくない理由を明確にするために、変換コードを型にとらわれないようにしたいと思います。この特定の文字列型に c_str が実装されていることがわかっているという事実にコードを依存させたくありません。 ObjectDebugName によって別の文字列クラスが返される場合でも、または ObjectDebugName が既に const char * を返している場合でも (これにより、.operator const char *() を呼び出す可能性が排除されます)、それを機能させたいと考えています。