2012-09-25 5 views
6

コンパイル時にC++ 11では、2つのテンプレートパラメータを取るテンプレート関数で、どちらも符号なし整数型でなければなりません。ローカル変数に2つのテンプレートパラメータのいずれかの型を持たせたいビット。私はこれをより簡単にするために、新しいC++ 11個の機能のいずれかを利用することができますC++ 11大きな整数型を選択するためのテンプレートを書くには?

template<bool, class T, class U> 
struct pick_first; 

template<class T, class U> 
struct pick_first<true, T, U> { 
    typedef T type; 
}; 

template<class T, class U> 
struct pick_first<false, T, U> { 
    typedef U type; 
}; 

template<class T, class U> 
struct pick_bigger { 
    typedef typename pick_first<(sizeof(T) >= sizeof(U)), T, U>::type type; 
}; 

// usage 
template<class uintX_t, class uintY_t> 
void foo() { 
    typename pick_bigger<uintX_t, uintY_t>::type mylocal = 0; 
    // insert doing stuff with mylocal here 
} 

:?C++ 03で私のような何かを書くかもしれませんか私はvariadicテンプレートを使用して複数の型のペア以上で動作させることができ、pick_firstを使用する代わりに、新しいint_leastX_t型とint_fastX_t型で動作させるために多くの特殊化を書くことができました。しかし、これに平易なアプローチがあるのであれば私は不思議です。おそらく何とかauto/constexpr/decltypeを活用していますか?

+4

あなたは 'std :: common_type'と考えましたか? –

+0

std :: common_typeについて聞いたことがありませんでした!とても興味深い。これは私のために働くだろう。私はあなたに投票できるので、回答として投稿する必要があります) –

+0

@DavidRodríguez-dribeasしかし、 'common_type'は整数昇格の規則のために常に動作するとは限りません。たとえば、 'std :: common_type :: type'は' int'です。これは、2つの型のどちらよりも大きい場合があります。 – Praetorian

答えて

7

あなただけの両方のタイプを含むいくつかの式の結果を保持するのに適したタイプをしたいとそうでない場合は、

template<class T, class U> 
struct wider { 
    using type = typename std::conditional<sizeof(T) >= sizeof(U), T, U>::type; // I'm using the C++11 type alias feature 1) to educate people about them and 2) because I like them better than typedefs. 
}; 

を書くことができるようにあなたのpick_firstは、ただのstd ::条件C++ 11でありますそこでtypenameが欠落している

template<class uintX_t, class uintY_t> 
void foo() { 
    typename std::common_type<uintX_t, uintY_t>::type mylocal = 0; 
    // insert doing stuff with mylocal here 
} 

// or 
template<class uintX_t, class uintY_t> 
void foo(uintX_t x, uintY_t y) { 
    auto mylocal = x + y; 
} 

とpick_biggerの実装:必ずしも正確に2種類、その後std::common_typeの1、または多分autoを必要とし、最適なソリューションですtypedef typename pick_first<(sizeof(T) >= sizeof(U)), T, U>::type type;

+0

これは、最も使用されているコンパイラでコンパイルされないコードを使って複雑なテンプレートマジックを追加して、OPが型を必要とするローカル変数に準最適な型を生成します。それは非常に愚かです。しかしそれは賢明に見える。 –

+0

うわー、std :: conditionalのどちらか、甘いことを知らなかった。 –

+0

@JosephGarvin http://en.cppreference.com/w/cpp/typesをご覧ください。新しいタイプのすべての特徴が表示されます。 – bames53

1

両方の型が符号なしなので、decltype(T1() + T2())とするだけです。

+5

これは、integer_typeとして宣言型(char()+ short())がint型の整数型宣言で同じ問題を抱えています。それが受け入れられるならば、common_typeを直接使うのが最良の解決策です。 – bames53

+0

@ barnes54:common_typeはヘッダー依存関係を追加します。その必要はありません。 'unsigned int'を' short'にする代わりに、OPはローカル変数に適した型を要求しています。最も適切な型は、変換なしで直接式の結果を格納できる型です。それがこの表現が生み出すものです。最も適切なタイプは、愚かな過剰設計のテンプレートセレクターが生成するものではないということです。 –

+0

@downvoter:あなたのdownvoteを説明してください。私は知っている、解説は、バーンズ53の三重upvotedコメントと同じように、合理的であると思います。そして、私はおそらくそれについてコメントするつもりもないでしょう。完全性のためだけです。 –

関連する問題