2017-02-13 5 views
0

私はflagsクラスを持っていますが、整数の周りのラッパーにすぎず、基になる整数型の変換ルールに基づいて任意の整数型への明示的な変換を実装したいと考えています。C++の明示的積分ユーザー定義変換

すなわち

unsigned long long iflags = static_cast<unsigned long long>(flags); 
で言う、私はまだint型以外の整数型に変換することができ

class Flags { 
    unsigned int v; 
    explicit operator unsigned int() { return v; } 
} 

私は(非関連メンバーを無視して)の線に沿ってクラスを持っていると言います

ではなく、

unsigned long long iflags = static_cast<unsigned int>(flags); 

とするか、これを行うには整数型ごとに変換演算子を明示的に定義する必要がありますか?私はhttp://en.cppreference.com/w/cpp/language/cast_operatorを読んだが、私は私が避けたいすべての有効な変換を定義し、明示的に必要があると思わせる整数型に特有の任意のものを見ることができないC++ 14

を使用してい

注意。また、もし私が内部整数の最大値を知っていることに注目すると、ターゲットタイプへの変換が不可能なテンプレート変換関数に満足しています。つまり、すべてのフラグビットがマクロ/定数FLAGS_MAXどんな用途のものでもあります。

+0

コンパイラにはバグや非標準の拡張機能が含まれているかもしれませんが、*試しただけでヒントを得ることができます。 –

+0

'explicit' *変換演算子*は、明示的に、または意図的にキャストする必要があります。 'static_cast (flags);'を実行すると、変換演算子 '演算子unsigned long long()'が要求されます。これはあなたのものではないので、プログラムは不正です。 – WhiZTiM

+0

最初のポイントは、最初のポイントが最初のポイントですが、誰も天気予報を言いませんでした。テンプレートを使用して、有効なすべての整数変換を定義し、フラグクラスのサイズを指定するという簡単な方法です。私は暗黙的な変換のためにこれがうまくいくことも理解していますが、偶然の変換を避けるため、クラスを暗黙的に整数型に変換することは望ましくありません。しかし、ターゲットタイプがすべてのフラグビットを保持できる限り、明示的な変換を行うときに基になるタイプが何であるかを考える必要はありません。 – glenflet

答えて

1

私はまだint型いいえ、あなたはできません

unsigned long long iflags = static_cast<unsigned long long>(flags); 

で言うよりも、他の整数型に変換することができます。

unsigned long long temp(flags); 
unsigned long long iflags = temp; 

flagsが暗黙的にunsigned long longに変換することはできませんので、最初の行が間違っている:

上記と同じです。

unsigned long long iflags = static_cast<unsigned int>(flags); 

あなたは

class Flags { 
    unsigned int v; 
    public: 
     operator unsigned int() { return v; } 
} 

その後、変換演算子からexplicit修飾子を削除する場合:iflagsを初期化するFlags、唯一の合法C++メソッドの定義を考えると

使用することですあなたは使用できます

試みは大体あなたは変数発明し、いくつかのために T t(e);を行うことができれば、あなたが static_cast<T>(e)を行うことができますことを言う [expr.static.cast]/4、該当
+0

「標準変換シーケンス」とは何が関係していますか? –

+0

@ T.C。、 'Flags' - >' int'が標準変換であれば 'Flags'を' unsigned int'に変換し、 'unsigned int'を' unsigned long long'に変換できます。それは私の考えでした。 –

+0

だから? '演算子unsigned int'が' explicit'ではないが、これはまだ標準変換ではない。いずれにせよ、これは暗黙の変換シーケンスを形成する能力とはあまり関係がありません。もちろん、*明示的*変換関数は、*暗黙の*変換シーケンス、標準であるかどうか、正確なタイプの一致を形成するために使用することはできません。 –

1

ことt(保証エリジオンとCスタイルのキャストの奇妙の世話をする文言でいくつかの楽しいダンスがあります、私たちの目的のために無視することができます)。あなたが候補者について言うためにこれを持っている[over.match.conv]へのポインタでFlagsの変換関数のオーバーロードの解決を、やると言う初期化が[dcl.init]/17.7によって制御される

、:

これらの非明示的な変換関数 [Flags]内に隠されておらず、標準タイプの シーケンスを介して をタイプ[unsigned long long]に変換できるタイプは、候補機能です。直接初期化するため、[Flags]と 収率タイプ[unsigned long long]または資格変換と タイプ[unsigned long long]に変換することができるタイプの中に隠されていないもの 明示的な変換関数も 候補となる関数です。

あなたexplicit operator unsigned int()どちら利回りunsigned long longも資格変換を経由して、それに変換できるタイプ(ここでは無関係です - 変換はポインタのみ-yのものに適用されること)。したがって、それは候補者ではない。候補セットは空であるため、オーバーロードの解決に失敗して初期化が正しく行われないため、static_castも同様です。

関連する問題