So I have a vector of pointers holding a baseclass. I create two elements inside the vector and then attempt to swap them after a few layers of abstraction. Currently this causes the compiler to explode and throw several errors inside move.h that look like this:
*c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/move.h: In function 'void std::swap(_Tp&, _Tp&) [with _Tp = Base]':
D:\My Documents\pointertest2\main.cpp:52: instantiated from here
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/move.h:81: error: cannot allocate an object of abstract type 'Base'
D:\My Documents\pointertest2\main.cpp:7: note: because the following virtual functions are pure within 'Base':
D:\My Documents\pointertest2\main.cpp:11: note: virtual int Base::GetInt()
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/move.h:81: error: cannot declare variable '__tmp' to be of abstract type 'Base'
D:\My Documents\pointertest2\main.cpp:7: note: since type 'Base' has pure virtual functions*
The code that causes this problem is as follows:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class Base {
public:
virtual int GetInt() = 0;
int a;
};
class Test : public Base {
public:
int GetInt()
{
return a;
}
};
class Slot {
public:
Base *connected;
};
int main()
{
std::vector<Base*> testVec;
Base *test = new Test;
testVec.push_back(test);
testVec[0]->a = 1;
Base *test2 = new Test;
testVec.push_back(test2);
testVec[1]->a = 2;
Slot slot;
slot.connected = testVec[0];
Slot slot2;
slot2.connected = testVec[1];
Slot* slottemp = &slot;
Slot* slottemp2 = &slot2;
std::swap(*slottemp->connected, *slottemp2->connected);
cout << testVec[0]->GetInt() << endl;
cout << testVec[1]->GetInt() << endl;
return 0;
}
You can see at the end i’m hoping that testVec[0] will return 2, and testVec[1] will return 1, as these are the swapped values i’m looking for.
Any help would be greatly appreciated, my head has been exploding on this one. I’m entirely open to alternate methods of swapping the pointers contained as elements 0 and 1, this is just where i’ve ended up at so far.
You’re trying to swap objects of type
Base.slottemp->connectedis of typeBase *, so by swapping*slottemp->connected, you’re swapping twoBase &. Since there’s nostd::swapoverload forBase &, the compiler falls back to the default, which goes something like this:If we instantiate this on
T = Base, then we try to construct a temporaryBasefor the swap; this fails, becauseBasehas pure virtual functions.One option is to write a
std::swapoverload forBase:This will allow you to swap the underlying
Bases. However, this is unlikely to be well-suited to a virtual base class – what happens if someone tries to swap aFooand aBar, both derived fromBase?If you just want the
Slots swapped, you can swap theBase *s, not theBases themselves:If you want the changes to be reflected in the
vector, you should makeSlothold an iterator, or a pointer to the pointer inside the vectorIn this particular case, you know the true type is
Test, so you can also cast to this concrete type and swap that way:I wouldn’t recommend this approach, as it invites the possibility of slicing (or worse, illegal casting) later if you start adding values of type other than
Testto the vector.