static_castとImplicit_castの違いは何ですか?
-
22-08-2019 - |
質問
implicit_castは何ですか?とき、私はむしろ、static_castをよりimplicit_castを好むでしょうか?
解決
私は<のhref = "https://stackoverflow.com/questions/385556/how-does-c-pick-which-overloaded-function-to-call/394742に私が作ったコメントからオーバーコピーしています#394742" >別の場所でこのコメントを答えます。
あなたは
static_cast
でダウンキャストすることができます。ないimplicit_cast
とそう。static_cast
は基本的にあなたが任意の暗黙の型変換を行うことができ、かつ任意の暗黙的な変換の他に、リバース(いくつかの制限まで。あなたは意気消沈することはできません関与仮想基底クラスがある場合)。しかし、ののみの暗黙の型変換をimplicit_cast
受け入れます。ノーダウンキャスト、無void*->T*
、TはUのためにのみ明示的なコンストラクタを持っている場合は、noU->T
ます。
それはキャストとコンバージョンの違いに注意することが重要だということに注意してください。以下なしのキャストで起こっている。
int a = 3.4;
しかし、暗黙の型変換がintにdoubleから起こります。キャストは常に明示的な変換要求であるため、「暗黙のキャスト」のようなものは、存在しません。 boost::implicit_cast
の名前構築物は、「暗黙の型変換を使用してキャスト」の素敵な組み合わせです。今boost::implicit_cast
の全体の実装は、これがある(説明ここを):
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!
どのような望まれていたことは、
このようにそれを記述することですcall_const_version(implicit_cast<MyClass const*>(this)); // right!
コンパイラは、どのようなタイプのテンプレートパラメータDst
を推測することはできません、それは最初にそれが控除のために使用されるパラメータの一部であることから、何であるかidentity<Dst>
知っていなければならないので、名前を付ける必要があります。しかし、それは順番にパラメータDst
(identity
が明示的にいくつかの種類に特化することができる)に依存します。今、私たちは、標準は、まさにこのようなパラメータは非推測コンテキストで言うれる循環依存関係を持って、明示的なテンプレート引数を指定する必要があります。
他のヒント
implcit_castを好みます。 implicit_castはそれほど強力とはstatic_castよりも安全です。
例えば、誘導されたポインタにベースポインタからダウンキャストするimplicit_castとはstatic_castではないで可能です。周りの他の方法は、両方のキャストで可能です。あなたは両方のクラスを混同している場合、それはあなたが安全に保つため、そして、派生クラス、ユースimplicit_castにベースからキャストます。
またimplicit_castがしばしば必要とされていないことに注意してください。 「暗黙の」はどこから来るimplicit_castはありませんほとんどの時間、すべての作品に何のキャストを使用していない、というのです。 implicit_castのみ例えば、式の型が正確に過負荷を避けるために、制御されなければならない特別な状況で必要とされます。
の implicit_cast の別のタイプを変換し、別のタイプからキャストし、暗黙のキャスト関数を書くことによって拡張することができる。
例えば。
int i = 100;
long l = i;
と
int i = 100;
long l = implicit_cast<long>(i);
はまったく同じコード
しかし、あなたは次の
のようにのimplicit_cast をオーバーロードすることで、あなた自身のタイプのために、独自の暗黙のキャストを提供することができますtemplate <typename T>
inline T implicit_cast (typename mpl::identity<T>::type x)
{
return x;
}
の詳細については、ブースト/ implicit_cast.hppするこちらを参照してください。
ホープ、このことができます。
編集
このページは語るimplicit_cast 新しいC ++ の
また、のstatic_castをするの主な機能は、別のタイプの非変更またはセマンティック変換を行うことです。タイプの変更が、値は同一のまま、例えば
void *voidPtr = . . .
int* intPtr = static_cast<int*>(voidPtr);
私はそれがint型のポインタであるかのように、ポインタは変更されません、このボイドポインタを見てみたい、とカバーの下voidPtrはのIntPtrとまったく同じ値を持ちます。 タイプの変更、
のimplicit_castのが、変換後の値があまりにもdiffernetのことができます。暗黙の変換、明示的な変換とはstatic_castはすべて異なるものです。あなたが暗黙的に変換できる場合は、明示的に変換することができ、かつ明示的に変換することができれば、あなたは静的にキャストすることができます。他の方向に同じしかし、真実ではありません。暗黙のキャストとの間に完全に合理的な関係があります 静的なキャスト。前者は後者のサブセットである。
の詳細についてはC ++標準のセクション5.2.9.3を参照してください
それはプログラム内の変換は「可視」なるので、それ以外の場合は、式eをすることができ 明示的に使って型Tに変換 フォームのはstatic_cast static_- 宣言T tの(E)と(e)をキャスト。 いくつかの発明のために、よく形成されています。 一時的な変数t(8.5)。
C ++はstatic_castsの使用を奨励します。キャストの使い方自体は一見とても良く利用はstatic_cast価値があるいくつかのプログラマ施行規則を示します。