我正在开发一个带图书馆的项目,我必须与工会合作。具体来说,我正在使用SDL和SDL_Event union。我需要复制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: 这太愚蠢......我认为Deqeues pop()成员返回了删除的项目。我认为代码非常简单,不能直接成为我的代码,但事实证明这是错误的。
我的代码看起来像:
for(SDL_Event CurrentEvent; !DequeueOfSDLEvents.empty(); CurrentEvent = DequeueOfSDLEvents.pop() )
{
//Do stuff
}
所以,如果没有别的,我将学会更仔细地查看我最近没有使用过的容器的成员函数。感谢您解释默认情况下的分配工作,否则需要更长时间才能找到它。
答案 0 :(得分:5)
在联盟中,元素都占据相同的记忆,就像它们彼此叠加一样。如果你写入联盟的另一个元素,它会覆盖其他元素。
因此,逐个元素复制是浪费时间。你可以只复制最大的元素,但是你必须知道它是哪一个(并不是每个元素的元素必须是相同的大小)最好的办法就是memcpy union。
但它比这更简单,你应该能够做一个赋值,并且编译器,意识到你正在复制一个结构或联合,将隐式地为你做“memcpy”。
答案 1 :(得分:3)
由于联盟(根据定义)只允许包含POD,因此您可以安全地使用memcpy
来复制它们。
答案 2 :(得分:1)
我可能弄错了,但工会不支持开箱即用的任务吗?
#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 =,但是你想要与正常的默认赋值有什么不同呢?
答案 3 :(得分:0)
看起来像boost::variant
的典型用例[编辑] 为什么不合适?
#define BOOST_VARIANT_LIMIT_TYPES 14
typedef boost::variant<Uint8, SDL_ActiveEvent, SDL_KeyboardEvent, ...,SDL_SysWMEvent> MyEvent;
答案 4 :(得分:0)
一般来说,您可以使用编译器生成的赋值运算符。我能想到的唯一例外是,如果你有一个可以包含指针的联合,并且你想为该指针实现一个深拷贝。为了更好地处理它,你必须使它成为一个有区别的联合,这样你就可以确定类型并适当地复制指针。但是,只要您没有远程所有权,编译器生成的赋值(和copy ctor)就可以正常工作。
答案 5 :(得分:0)
你不需要做任何特别的事情。在我看来,重载或添加运算符只会增加复杂性。 SDL_event是一个简单的unsigned char。
SDL_Events a;
SDL_Events b;
a = b; // this will copy the value