2011-02-23 6 views
0

char、short、longおよびlongの長さのクラステンプレートを特化したいと思います。この特殊化は、整数型の符号付きおよび符号なしバリアントにも有効です。char型のun/signednessを削除する

私はboostライブラリとstd :: tr1/C++ 0xがis_signed/is_unsignedとmake_signed/make_unsigned type_traitsを実装していることを知っています。しかし、どのように署名された仕様をchar型から取り除くことができますか(注:唯一の整数型で、署名されたitype!= itype)?

+0

なぜこのようなものが必要でしょうか?いくつかの数学的計算を行っているならば、http://www.cplusplus.com/reference/std/limits/numeric_limits/を使用してください。 –

答えて

4

charの「符号」は実装定義です。負の数を格納する必要はありません。厳密な標準では、 は決して符号付き整数型でも、実装に負の数を格納することができます。それでも、クラステンプレートis_signedは、charの場合はtrueと報告します。これは、負の数値を格納できる場合に便利です。

とにかく、あなたの目的のために使うことができるように、昇進のドキュメントは約make_unsignedについて次のように言います。

Tが符号付き整数型で、Tが符号付き整数型の場合は対応する符号なし型の場合はTと同じ型です。 Tが列挙または文字型(charまたはwchar_t型)であり、そうでない場合、次いでthe sourcemake_unsignedからT

+0

それでも、 'signed'または' unsigned 'を特定の型に対して2つの特殊化を使用してchar型から削除します。または私はここに何かを逃していますか? –

+0

@David私は実際に質問を理解することができないので、「署名された文字を取り除くためにcharをunsigned charに変更したい」というように読むことは、どう解釈するかです。確かにあなたの質問の読んでも合理的に見えます。 –

+0

ここでの情報 - 正しい解釈がどちらか一方であるか - 実際に貴重なものであることを、あなたが*元に戻す*ことを決めたことは良いことです。 –

0

と同じ幅を持つ符号なし整数型は依然としてチャーでも動作すべきです。そうでなければ見つかりましたか?あなたのプラットフォームでcharunsigned charに相当する場合は、明示的なsigned charタイプにのみ影響します。

4

かなりマニュアルと起こってほとんどの魔法が、あなたはcharからsigned/unsignedを削除したい場合は、このテンプレートを使用することができます。

template <typename T> 
struct remove_sign_from_char { 
    typedef T type; 
}; 
template <> 
struct remove_sign_from_char<signed char> 
{ 
    typedef char type; 
}; 
template <> 
struct remove_sign_from_char<unsigned char> 
{ 
    typedef char type; 
}; 

int main() { 
    static_assert(std::is_same< char, remove_sign_from_char<unsigned char>::type >::value); 
    static_assert(std::is_same< char, remove_sign_from_char<signed char>::type >::value); 
    static_assert(std::is_same< char, remove_sign_from_char<char>::type >::value); 
    static_assert(std::is_same< int, remove_sign_from_char<int>::type >::value); 
} 
0

さて、私はかなり格好良い解決策を見つけました:

template<typename itype, typename = void> struct my_typedef; 
/* ----------------------------------------------------------------------------------------------------- */ 

template<> 
struct my_typedef<char> 
{ 
    typedef char   type; 
    typedef signed char signed_type; 
    typedef unsigned char unsigned_type; 
}; /* template<> struct my_typedef<char> */ 
/* ----------------------------------------------------------------------------------------------------- */ 

template<> 
struct my_typedef<short> 
{ 
    typedef short   type; 
    typedef signed short signed_type; 
    typedef unsigned short unsigned_type; 
}; /* template<> struct my_typedef<short> */ 
/* ----------------------------------------------------------------------------------------------------- */ 

template<> 
struct my_typedef<long> 
{ 
    typedef long   type; 
    typedef signed long signed_type; 
    typedef unsigned long unsigned_type; 
}; /* template<> struct my_typedef<long> */ 
/* ----------------------------------------------------------------------------------------------------- */ 

template<> 
struct my_typedef<long long> 
{ 
    typedef long long   type; 
    typedef signed long long signed_type; 
    typedef unsigned long long unsigned_type; 
}; /* template<> struct my_typedef<long long> */ 
/* ----------------------------------------------------------------------------------------------------- */ 

template<> 
struct my_typedef<signed char> 
{ 
    typedef my_typedef<char>::type   type; 
    typedef my_typedef<char>::signed_type signed_type; 
    typedef my_typedef<char>::unsigned_type unsigned_type; 
}; /* template<> struct my_typedef<signed char> */ 
/* ----------------------------------------------------------------------------------------------------- */ 

template<typename itype> 
struct my_typedef<itype, typename std::enable_if<std::is_unsigned<itype>, void>::type> 
{ 
    typedef typename my_typedef<typename std::make_signed<itype>::type>::type type; 
    typedef typename my_typedef<typename std::make_signed<itype>::type>::type signed_type; 
    typedef typename my_typedef<typename std::make_signed<itype>::type>::type unsigned_type; 
}; /* template<typename> struct my_typedef<signed itype> */ 
/* ----------------------------------------------------------------------------------------------------- */ 
+0

私はあなたがここで何をしようとしているのかよく分かりません。最後のテンプレートの特殊化は基本的に 'std :: is_same :: unsigned> :: value == false'と言っていますか?これが意図的だった場合、少なくとも誤解を招くものではありません: 'my_typedef <...> :: unsigned'は署名型です。 –

関連する問題