I want to ask for an alternative solution to this problem. I am dealing with this C/C++ style interface that has this non-moveable type NonMovableType defined roughly as follows:
union union_type {
int index;
const char* name;
};
struct NonMovableType
{
std::initializer_list<union_type> data;
};
This is something I cannot change, despite the unfortunate use of unions and initializer lists. We then have some container of this type, say
std::vector<NonMovableType> container
and we want to split container based on some predicate for each of its members. Now, if it was a movable type i'd do
std::vector<NonMovableType> container;
std::vector<NonMovableType> result;
auto iter = std::partition(container.begin(), container.end(), [](const NonMovableType& element){
return element.data.size(); // the predicate
});
std::move(iter, container.end(), std::back_inserter(result));
container.erase(iter, container.end());
I could then trust container and result would contain the elements split by the predicate, that way I could then iterate over each one individually and do the necessary processing on them.
This wont work however because std::move and std::partition both require a movable type. Instead I have to result to the rather slow:
std::vector<NonMovableType> container;
std::vector<NonMovableType> result_a;
std::vector<NonMovableType> result_b;
std::copy_if(container.begin(), container.end(), std::back_inserter(result_a), [](const NonMovableType& element){
return element.data.size();
});
std::copy_if(container.begin(), container.end(), std::back_inserter(result_b), [](const NonMovableType& element){
return !element.data.size();
});
container.clear();
And so, my question is, is there any better way to do this? I suppose calling it a 'non movable type' may be wrong, its only the union and the initializer list which are giving me problems, so really the question becomes is there a way to move this type safely, and do so without having to change the initial class. Could it also be possible to wrap NonMovableType into another class and then use pointers as opposed to a direct type?