2009-05-15 2 views
12

implicit_castとは何ですか? static_castではなくimplicit_castをいつ優先すべきですか?static_castとImplicit_castの違いは何ですか?

+5

あなたがabt boost :: implicit_castを要求している場合に備えて、もっともっとはっきりと言うために投稿を編集してください。 – Abhay

+0

@Abhay 'implicit_cast'のコンセプトは、数年前のBoostよりもずっと古いものです。 – curiousguy

+0

@curiousguy:キャストは常に明示的な変換要求であるため、「暗黙のキャスト」のようなものは存在しません。詳細については受け入れられた答えをお読みください。 – Abhay

答えて

18

他の場所でanswer this commentに行ったコメントからコピーしています。

static_castでダウンキャストできます。そうでないとimplicit_castとなります。 static_castは基本的に暗黙的な変換を行うことができます。また、暗黙的な変換の逆も可能です(いくつかの制限がありますが、仮想ベースクラスが含まれているとダウンキャストできません)。しかしimplicit_castは暗黙の変換を受け入れます。ノーダウンキャスト、ノーvoid*->T*、ノーU->T Tは、キャストとコンバージョンの違いに注意することが重要だとU.

注唯一の明示的なコンストラクタを持っている場合。以下ではキャストは行われない。

int a = 3.4; 

しかし、暗黙の変換はdoubleからintに起こる。キャストは常に明示的な変換要求であるため、「暗黙のキャスト」のようなものは存在しません。 boost::implicit_castの名前構成は、「暗黙の変換を使用したキャスト」の素敵な組み合わせです。今boost::implicit_castの全体の実装は、これは(hereを説明した)である:

template<typename T> struct identity { typedef T type; }; 
template<typename Dst> Dst implicit_cast(typename identity<Dst>::type t) 
{ return t; } 

アイデアは、パラメータtのために非推測コンテキストを使用することです。それは次のような落とし穴を避けることができます:

call_const_version(implicit_cast(this)); // oops, wrong! 

何望まれていたが、それ最初ため、コンパイラは、名前を付ける必要がありますどのような種類のテンプレートパラメータDst推測することはできません。この

call_const_version(implicit_cast<MyClass const*>(this)); // right! 

のようにそれを記述することですそれが控除に使用されるパラメータの一部であるため、identity<Dst>が何であるかを知る必要があります。しかし、それはパラメータDstに依存します(identityは、いくつかのタイプに対して明示的に特殊化されている可能性があります)。さて、我々は循環依存性を得ました。標準では、このようなパラメータは推論されていないコンテキストであり、明示的なテンプレート引数が提供されなければならないとしか言​​いません。

1

implicit_castは、1つの型を別の型に変換し、ある型から別の型にキャストする暗黙のキャスト関数を記述することで拡張できます。

int i = 100; 
long l = i; 

int i = 100; 
long l = implicit_cast<long>(i); 

template <typename T> 
inline T implicit_cast (typename mpl::identity<T>::type x) 
{ 
    return x; 
} 
よう implicit_castに過負荷をかけることで、あなた自身のタイプのために、独自の暗黙のキャストを提供することができますが、まったく同じコード

です

ここをクリックしてくださいより

ホープこのまたNew C++

static_castをの主な機能は非変更またはセマンティック変換を実行することであるimplicit_cast程度

EDIT

このページにも交渉を支援しますあるタイプから別のタイプへタイプは変わるが、値は同一のままである。

void *voidPtr = . . . 
int* intPtr = static_cast<int*>(voidPtr); 

私はそれがint型のポインタであるかのように、ポインタは変更されません、このボイドポインタを見てみたい、とカバーの下voidPtrはのIntPtrとまったく同じ値を持ちます。 implicit_castの場合、型は変更されますが、変換後の値も異なる場合があります。

+1

"_ static_castの主な機能は、あるタイプから別のタイプへの非変更またはセマンティック変換を実行することです。このタイプは変更されますが、値は同じままです(この場合(' static_cast '))。 static_cast (3.14) ' – curiousguy

1

暗黙的な変換、明示的な変換、およびstatic_castはすべて異なるものです。ただし、暗黙的に変換できる場合は明示的に変換でき、明示的に変換できる場合は静的にキャストできます。しかし、他の方向への同じことは真実ではない。暗黙キャストと 静的キャストの間には完全に合理的な関係があります。前者は後者のサブセットです。

詳細

ためのC++標準の参照セクション5.2.9.3そうでない場合、式eは、明示的 場合形態static_- キャスト(E)のはstatic_castを使用して型Tに変換することができます。宣言T t(e); 一時変数t(8.5)が発明されたため、 は整形式です。

C++では、プログラムで変換が「可視」になるため、static_castsの使用を推奨しています。キャスト自体の使用法は、一見価値があるプログラマが強制するルールを示していますので、static_castを使用する方がよいでしょう。

4

あなたの状況で十分であれば、implcit_castを優先します。implicit_castはstatic_castよりも強力で安全です。

たとえば、static_castではベースポインタから派生ポインタへのダウンキャストが可能ですが、implicit_castではダウンキャストはできません。それ以外の方法は両方のキャストで可能です。次に、ベースクラスから派生クラスにキャストするときは、両方のクラスを混同しても安全ですので、implicit_castを使用してください。

また、implicit_castはしばしば必要ではないことに注意してください。 implicit_castが行うほとんどの場合、キャストなしのすべての作品を使用します。それは、暗黙的なものです。 implicit_castは、例えば過負荷を避けるために、式の型を厳密に制御しなければならない特殊な状況でのみ必要です。

+0

ここでは、「派生」と「ベース」を逆にしています。派生ポインタは常に(パブリックまたはアクセス可能な)ベースに変換できますが、ダウンコンバートには明示的なキャストが必要です。 –

+0

@ AdamH.Petersonそうです。私は答えを編集しました。 –

関連する問題