web-dev-qa-db-ja.com

構造体の外に自動キャスト演算子を書くことは可能ですか?

正確な状況は次のとおりです。システムAPI構造体CGPointCGSizeで定義しましたが、my_point = my_sizeを記述できるようにしたいと考えています。 CGPoint構造体を変更することはできず、外部演算子を書き込むことしかできません。二項演算子(+-、...)を記述できますが、operator=は構造体内で宣言する必要があります。それで、他の解決策はありますか?

23
brigadir

式_a = b;_をコンパイルするには、aタイプの要素をとるbタイプの_operator=_、またはbから暗黙的に変換可能なタイプのいずれかが必要です。

_operator=_はクラスのメンバーである必要があり、GLPointを変更できないため、GLPoint& GLPoint::operator=( GLSize )を追加できないため、最初のケースは除外されます。

2番目のケースも同じタイプの問題を抱えています。 GLSizeからGLPointへの暗黙的な変換は、GLPointの暗黙のコンストラクター(除外)として、またはGLSizeのメンバーoperator GLPoint()として実装できます。これにはGLSizeの変更が必要です。変換を無料の関数として追加することもできません。

代替案は、無料の関数assign(またはcopy)を追加するなど、演算子以外の構文を使用しています:GLPoint& assign( GLPoint&, GLSize const & )

次の質問は、なぜそうしたいのかということです。 GLPointGLSizeの設計者が、サイズをポイントに割り当てることができると考えていなかった場合、なぜそれらを割り当てることができると思いますか?一般に、型を分離しておくことをお勧めします。これにより、コンパイラーはコードで犯す可能性のある間違いを検出できるようになります。

GLSizeからGLPointへの暗黙的な変換を許可する場合、誤って次のように入力する可能性があります:distance( point1, size2 )ここでdistance( point1, point2 )を意味し、変換があるため、コンパイラは喜んで変換して適用します。次に、奇妙な結果が表示され、ロジックがどこで間違っているかを判断するために、かなりの数のNiceデバッグ時間を費やします。

ドメインがそのコンテキストで各演算子が何を意味するかについて非常に明確な定義を持っていない限り、私はどんな犠牲を払っても演算子のオーバーロードを避けます。 everyoneコードを読むと、GLPoint(1,2) + GLSize(5)が何を表しているのか、疑いやあいまいさなしにすぐに理解できますか?そうでない場合、人々が驚いたり疑ったりする場合は、演算子のオーバーロードを避け、名前付き関数を使用してください:move_up( GLPoint&, GLSize )(またはポイント+サイズが意味するもの)

CGSizeCGPointに割り当てると、どうなりますか?それをいくつかの演算子に蒸留すると、そこにそれがあります-たとえば

CGPoint& operator|=(CGPoint& cPoint, CGSize const& cSize)
{
  // now set attributes of cPoint that you can extract from cSize

  return cPoint;
}

これについて何がそんなに難しいのですか?次に例を示します。 http://www.ideone.com/FZN2

3
Nim

CGPointから派生またはラップして、コード全体で代わりに新しいクラスを使用できる場合は、任意の演算子を指定できます。新しいクラスには、既存の関数との相互作用を容易にするCGPointへの変換演算子を含めることができます。

2
Tony Delroy

明らかな解決策を見逃す他の答えの継ぎ目:CGPointをCGSizeに変換する関数を追加します。もちろん、それはあなたが望むものではありません(size = point)ただし、2つのクラスのどちらも変更できないため、これが唯一の方法です。

CGSize ToSize( const CGPoint &pt )
{
  CGSize res = ...
  // do the conversion
  return res;
}
1
BЈовић