web-dev-qa-db-ja.com

数値タイプ間でキャストするためのC ++のベストプラクティス

異なる番号タイプ間でキャストするためのベストプラクティスは何ですか?タイプfloatdoubleintは、私がC++で最もよく使用するタイプです。

ffloatで、ndoubleまたはintであるオプションの例:

_float f = static_cast<float>(n);
float f = float(n);
float f = (float)n;
_

私は通常static_cast<T>(...)と書きますが、好ましい方法があるかどうか、C++開発コミュニティ内でコンセンサスがあるかどうか疑問に思いました。

これが意見に基づく質問になり、「標準的な」方法がない可能性があることを感謝します。その場合、標準的な方法がないことを知らせてください。少なくとも私はそれを知っています:-)

私はこの質問が一般的なキャストに関して 切り取られた であることを知っています、しかし、私は特に数字と数字タイプのアプローチに特定のベストプラクティスがあるかどうかに興味があります。

11
keith

static_castを使用するだけです。 Cキャストの問題は、操作のあいまいさです(つまり、 明示的な型変換 のポイント(1))。

C++キャストはこれを回避します。さらに、C++キャストは、それらを検索するときに見やすくなります。

Stroustrupの言葉を使用する( static_castは何が良いですか? ):

開発やメンテナンスの際に、関係するタイプの1つを変更すると、無邪気なキャストでさえ深刻な問題になる可能性があります。たとえば、これはどういう意味ですか?:

  x = (T)y;

わかりません。タイプTとxおよびyのタイプによって異なります。 Tは、クラスの名前、typedef、またはテンプレートパラメータの場合があります。たぶん、xyはスカラー変数であり、(T)は値の変換を表します。たぶん、xyのクラスから派生したクラスであり、(T)はダウンキャストです。たぶんxyは無関係なポインタ型です。 Cスタイルのキャスト(T)は、論理的に異なる多くの操作を表現するために使用できるため、コンパイラーは誤用を見つける可能性がほとんどありません。同じ理由で、プログラマーはキャストが何をするのか正確に知らないかもしれません。これは、初心者プログラマーにとっては利点と見なされることがあり、初心者が間違って推測した場合の微妙なエラーの原因になります。

「新しいスタイルのキャスト」は、プログラマーが意図をより明確に述べ、コンパイラーがより多くのエラーをキャッチできるようにするために導入されました。

[切る]

新しいスタイルのキャストを導入した第2の理由は、Cスタイルのキャストをプログラムで見つけるのが非常に難しいことでした。たとえば、通常のエディタやワードプロセッサを使用してキャストを簡単に検索することはできません。

[切る]

キャストは、最近のC++ではほとんど回避できます

また、より安全な代替手段である boost::numeric::converter / boost::numeric_cast も検討してください( Boost.NumericConversion ライブラリの一部)。

例えば。

#include <iostream>
#include <boost/numeric/conversion/cast.hpp>

int main()
{
  using boost::numeric_cast;

  using boost::numeric::bad_numeric_cast;
  using boost::numeric::positive_overflow;
  using boost::numeric::negative_overflow;

  try
  {
    int i = 42;
    short s = numeric_cast<short>(i); // This conversion succeeds (is in range)
  }
  catch(negative_overflow &e)  { std::cout << e.what(); }
  catch(positive_overflow &e)  { std::cout << e.what(); }

  return 0;
}

一般に、暗黙的な変換と明示的な変換(static_castによる)の両方で、範囲が保持されないため、数値タイプ間の変換でエラーが発生しやすくなります。

numeric_castは、数値型が変換されるときに範囲の喪失を検出し、範囲を保持できない場合は例外をスローします。

7
manlio