2010-12-12 5 views
14

は、最善の構文はboost::numeric_cast<>()を使用するようです:ブーストを使用する::私は異なる整数型の間で変換したい場合はnumeric_cast <>

int y = 99999; 
short x = boost::numeric_cast<short>(y); // will throw an exception if y is too large 

私はそれを使用したことがありません。構文はかなり単純です。したがって、すべてがうまくいきます。

もう少し先を進めたいと思います。例外をスローするのではなく、ターゲットタイプの最小値または最大値(彩度)を戻したいと思います。私はそれを表現する方法を理解することができませんでしたが、documentationはそれが可能であることを示唆しています(おそらくRawConverter方針を使用しています)。私が思い付くことができるすべては、次のように醜いです:

short x = numeric_cast<short>(max(min(y, SHORT_MAX), SHORT_MIN); 

は、どのように私は、ブーストのnumeric_castを使用して、「飽和キャスト」を表現することができますか?

答えて

15

あなたは、おそらくこのような何かを行うことができます:

#include <limits> 

template<typename Target, typename Source> 
Target saturation_cast(Source src) { 
    try { 
     return boost::numeric_cast<Target>(src); 
    } 
    catch (const boost::negative_overflow &e) { 
     return std::numeric_limits<Target>::lowest(); 
     /* Or, before C++11: 
     if (std::numeric_limits<Target>::is_integer) 
     return std::numeric_limits<Target>::min(); 
     else 
     return -std::numeric_limits<Target>::max(); 
     */ 
    } 
    catch (const boost::positive_overflow &e) { 
     return std::numeric_limits<Target>::max(); 
    } 
} 

を(も/ + INFを-inf返すことができ、それをエラーケースをサポートするタイプの場合)。

このようにして、Boostのnumeric_castは値が範囲外であるかどうかを判断し、それに応じて反応することができます。

+0

例外依存:(C++例外を使用しないプロジェクトもありますが、これは覚えておくと便利です) – Kos

+3

@Kos:プロジェクトですべての言語機能が使用されていない場合は、他の人がその機能を気に入らないかもしれないので、一部の機能を使用しない言語用のコードを書く必要はありません。 – Puppy

+0

例外は、すべての利点に加えて、制御フローを複雑にし、オーバーヘッドを招く可能性があります。多くの(すべてではない)C++プロジェクトは、例外なく存在するのが良い理由があり、例外サポートなしでコンパイルされています。 – Kos

2

フム...上記の作品ならば、一般的な解決策は、おそらく何かのようにするために、次のようになります。私はそれは右...とにかく、あなたはコンセプトを持って得た

template<typename TypeFrom, typename TypeTo> 
TypeTo saturated_cast(TypeFrom value) { 
    TypeTo valueMin = std::numeric_limits<TypeTo>::min(); 
    TypeTo valueMax = std::numeric_limits<TypeTo>::max(); 
    return boost::numeric_cast<TypeTo>(std::max(std::min(value,valueMax),valueMin)); 
} 

希望:)

.... BTW:制限を実行した後でもう範囲をオーバーフローすることができないので、を使用することができると思いますので、numeric_castの追加チェックは必要ありません。

+1

GregHillと同じ問題は、比較の前に変換が行われなければなりません。それ以外の場合は、numeric_castを使用するとメリットがありません。また、 'std :: min'と' std :: max'は同じ型の2つの引数に対してのみ呼び出すことができ、このコードはコンパイルされません。 –

関連する問題

 関連する問題