2

私は図書館のプロジェクトに取り組んでおり、労働組合と協力しなければなりません。具体的には、SDL とSDL_Event ユニオンを使用しています。SDL_Events のコピーを作成する必要がありますが、共用体を使用した代入演算子のオーバーロードに関する適切な情報が見つかりませんでした。

代入演算子をオーバーロードできる場合、手動でユニオン メンバーをふるいにかけ、適切なメンバーをコピーするか、単純にいくつかのメンバーを取得するか (これは危険に思えます)、単に memcpy() を使用するか (これは単純で高速に思えます) 、しかし少し危険です)?

演算子をオーバーロードできない場合、そこからの最良のオプションは何ですか? 新しいコピーを作成して一連のポインターを渡すこともできると思いますが、この状況ではそれを行いたくないでしょう。

どんなアイデアでも大歓迎です!

編集:要求されたエラーメッセージとして、そしてついでに私は何かを学んだと思います...

physworld.cpp:325: error: no match for ‘operator=’ in ‘CurrentEvent = ((physworld*)this)->physworld::SDL_UserInputEvents.std::queue<_Tp, _Sequence>::pop [with _Tp = SDL_Event, _Sequence = std::deque<SDL_Event, std::allocator<SDL_Event> >]()’ /usr/include/SDL/SDL_events.h:220: note: candidates are: SDL_Event& SDL_Event::operator=(const SDL_Event&)

EDIT2:これはとてもばかげていました... Dequeues pop() メンバーが削除されたアイテムを返したと思いました。コードが単純すぎて直接自分のコードにできないと思っていたのですが、それは間違っていることがわかりました。

私のコードは次のようになりました:

 for(SDL_Event CurrentEvent; !DequeueOfSDLEvents.empty(); CurrentEvent = DequeueOfSDLEvents.pop() )
 {
   //Do stuff
 }

したがって、最近使用していないコンテナーのメンバー関数を詳しく調べることを学べます。割り当てがデフォルトで機能することを説明してくれてありがとう。そうでなければ、これを見つけるのに時間がかかったでしょう。

4

6 に答える 6

6

ユニオンでは、要素が互いに重なり合っているように、すべての要素が同じメモリを占有します。共用体の別の要素に書き込むと、他の要素が上書きされます。

そのため、要素ごとにコピーするのは時間の無駄です。最大の要素のみをコピーすることもできますが、それがどれであるかを知る必要があります (ユニオンのすべての要素が同じサイズである必要はありません)。最善の方法は、ユニオンを単に memcpy することです。

しかし、それよりもさらに簡単です。割り当てを行うだけで、構造体または共用体をコピーしていることに気付いたコンパイラーは、暗黙的に「memcpy」を実行します。

于 2010-03-17T23:06:41.480 に答える
3

ユニオンは (定義により) POD のみを含むことが許可されているため、 を使用memcpyしてそれらを安全にコピーできます。

于 2010-03-17T22:57:59.127 に答える
2

私は間違っているかもしれませんが、組合はすぐに割り当てをサポートしませんか?

#include <cassert>

union X
{
    int a;
    double b;
};

int main()
{
    X x;
    x.a = 10;
    X y;
    y = x;
    assert(y.a == x.a);
}

また、通常どおり operator= をオーバーロードすることもできるようですが、通常のデフォルトの割り当てとは正確に何を変えたいのでしょうか?

于 2010-03-17T23:19:39.830 に答える
0

特別なことをする必要はありません。私の意見では、演算子のオーバーロードや追加は複雑さを増すだけです。SDL_event は単純な unsigned char です。

SDL_Events a;
SDL_Events b;

a = b;  // this will copy the value
于 2010-03-18T00:21:55.517 に答える
0

一般的に言えば、コンパイラで生成された代入演算子を使用できます。私が考えることができる唯一の例外は、ポインターを含む可能性のある共用​​体があり、そのポインターのディープ コピーを実装したい場合です。それをうまく処理するには、型を判別してポインターを適切にコピーできるように、判別共用体にする必要があります。ただし、リモート所有権を持っていない限り、コンパイラによって生成された割り当て (およびコピー ctor) は正常に機能するはずです。

于 2010-03-17T23:23:55.537 に答える
0

boost::variantの典型的な使用例のように見えます

[編集]なぜ適切ではないのですか?

#define BOOST_VARIANT_LIMIT_TYPES 14
typedef boost::variant<Uint8, SDL_ActiveEvent, SDL_KeyboardEvent, ...,SDL_SysWMEvent> MyEvent;
于 2010-03-17T23:10:29.140 に答える