2016-02-18 8 views
9

私はすでにここに何度も議論されたが、私の質問は数値型の間ではなく、CスタイルとCの間の一般的な違いについてのキャストについては、具体的できたC++で異なるキャスト演算子ことを認識しています++スタイルの演算子。私はこれをクラス階層内でのキャストとは全く別のトピックと考えています。C++鋳造

は、私が表現したいので、私は持っているオプションの一部は、個人的に私はこの場合は3行目では、コンストラクタのようなスタイルを

static_cast<double>(i) 
(double) i 
double(i) 

を好むが、私は二重にint型iをキャストしたいとこれは、私が確かにstatic_castまたはdynamic_castを使用するキャストベイトンクラスのタイプではないことを示します。

テキストエディタで検索するときにこのタイプのキャストを見つけることを困難にすることを除いて、私の選択の欠点はありますか?

+1

どのようなコンテキストですか?なぜキャストしなければならないのですか? –

+0

@Karoly Horvath:良い質問ですが、私はいつもキャストを避けようとしますが、私がこれを行う典型的なケースは、計算の範囲内であるか、関数の引数を渡すときです。 –

+4

「このタイプのキャストを見つけるのが難しい」というのは、決してそれを使用しない理由です。 –

答えて

4

この特定のケースでは、確かにあなたの意図を最も明確に表現しています。

数値型の間でキャストするとき、定義されていない動作が発生することがあります。だから一般的に注意してください。あなたのキャストはiの可能な値ごとに定義されていますが、doubleintにキャストするとintをオーバーフローする可能性があり、その動作はC++では定義されていません。

送信先の種類が送信元の種類に対応できるかどうかは、常に確認することをおすすめします。 std::numeric_limits<>::max()などがお手伝いします。

C++標準では最大サイズがint(16,32,64ビットの2の補数は共通)ですが、doubleとして表現されない可能性があります。私のコードで

私は私が必要とするすべての数値のキャストのための専門

template< 
     typename T/*the desired type*/, 
     typename/*the source type*/ Y 
    > T integral_cast(const Y& y) 
    { 
     static_assert(false, "undefined integral_cast"); 
    } 

を含む名前空間を持っています。

+2

'static_cast'はここで未定義の動作からあなたを守りません。そして、OPは、この特別な場合の彼らの好ましいキャストのための非常に良い点を与えた。 – StoryTeller

+0

確かに、それを書くのは非常に明確な方法です。しかし、 'int'から' double'へのキャストは常に*定義されていることに注意してください。 – Bathsheba

+0

それは意見に基づいています。確かに目立っていますが、 'int'から新しい' double 'を構築するという考え方も非常に明確です。 – StoryTeller

3

これらのアプローチの大きな欠点の1つは、キャストがオーバーフローやその他の数値エラーに対して安全でないことです。

static_castを使用すると、このメソッドは即時コード解決ツールであり、PVS studioのようなスタティックコードアナリストツールによってフラグが立てられません。 (double)iアプローチは警告を生成します。

は、おそらく最も安全なアプローチは、のは、この機能の利点は、あなたがキャストが正当なものであるとしないことを保証するためにバインドチェックや他の数値のチェックを行うことができるということですnumeric_cast<T>()

template <class OT, class ST> 
OT numeric_cast(const ST value) 
{ 
    return static_cast<OT>(value); 
} 

を言わせて、独自のキャストを持つことですジャンク値を返す(または取得する)。

数値を扱う別の方法がありますが、定数のコンパイル時の値でのみ機能します。このチェックではuser defined string literals