2013-03-23 11 views
13

私はboost :: promoteと同様の宣言テンプレートエイリアスを作成していますが、C++では11です。 varidic関数から引数を取り出す際の警告を避けるためです。例えば 1)intは) 2をint型に昇格されたフロートはenumクラスと通常のenumを区別するためのC++ 11型の特性

を倍に促進されるよりも小さいです整数:

template <typename T> 
std::vector<T> MakeArgVectorV(int aArgCount, va_list aArgList) 
{ 
    std::vector<T> args; 
    while (aArgCount > 0) 
    { 
     args.push_back(static_cast<T>(va_arg(aArgList, Promote<T>))); 
     --aArgCount; 
    } 
    return args; 
} 

テンプレートエイリアスを推進するには、可変長引数のデフォルトの引数のプロモーション以下のタイプを促進します私の問題は、標準のC++ enumを宣言できますが、C++ 11 enumクラスは宣言されていないことです(コンパイラは警告を生成しません)。私は通常のenumで動作するようにPromoteをしたいが、C++ 11 enumクラスは無視する。

私のプロモートテンプレートエイリアスのenumクラスとenumの違いを教えてください。ここ

+1

本当の問題は、 'std :: initializer_list'やバリデーションテンプレートの代わりに' va_arg'sを使っていることです。 – Fanael

+0

チップをありがとうが、私はCのインターフェイスで作業しているので、私はva_listを持っています。 – Sam

+0

@Sam:私の答えはあなたの問題を解決していますか? –

答えて

21

は可能な解決策である。

#include <type_traits> 

template<typename E> 
using is_scoped_enum = std::integral_constant< 
    bool, 
    std::is_enum<E>::value && !std::is_convertible<E, int>::value>; 

溶液はC++ 11標準の段落7.2/9で指定されたスコープとスコープ外の列挙の間の挙動の違いを利用します列挙子またはスコープのない列挙型のオブジェクトの値は、整数昇格(4.5)によって整数に変換されます。 [...]この暗黙的なenumからintへの変換は、スコープ付き列挙に対しては提供されていません。 [...]

をここでは、あなたがそれを使用する方法のデモンストレーションです:

そして、ここではlive exampleです。

謝辞:私の以前のアプローチは、唯一の限りoperator +のないユーザ定義の過負荷が存在しないとして働くだろうと指摘しDaniel Freyから

感謝。

+3

+1ですが、1つの洞窟があります:いくつかのenumクラス 'E'の作成者が自分自身の' operator +(int、E) 'を定義していない限り動作します。 'voidダミー(int)'を追加し、 'decltype(dummy :: std :: declval ())')を使って修正してください。 –

+1

@DanielFrey:良い点。実際には、ユーザ定義演算子オーバーロード –

+1

@AndyProwlを妨害する可能性を低くするために、 '^'などの別の演算子を使用することも、 'int'をとる関数を呼び出すこともできます。 – Fanael