Is there any way I can check is std::move done on some STL container?
I have two types of classes (lets say A and B), they keep (some) instances of another class in their internal container. If instance of A keeps instance of B in it's container, that instance of B have to keep the same instance of A in it's container, too.
A can see B's private methods (B has it as it's friend), but I have to implement move constructor on B. As B can see both's internal container, I've implemented B does all adding and removing for both classes.
Problem is:
I have to implement move constructor for A, and use stl::move on that container. After container is moved to new instance of an A, only way to notify B of detachment of old class is through the method that uses B's, and old A's container and does removing for both of classes.
Is there any way for B to know that old A's container is moved and it shouldn't acces it?
It works without checking, but as class doesn't have defined state after std::move, I shouldn't call ::remove() on it (professor says it's an error).
Please note: this is my homework problem, so I wouldn't like to get illegal help of solving complete problem, only the part of checking of object's consistency to skip calling it's functions after moving it.
EDIT: added example.
IMPORTANT:
1) I'm required to use std::move. I already know an easy way to do everything in while-loop using iterators. But, std::move is explicitly required.
2) This snippet is for understanding my problem. As student, I'd like to solve it by myself, I only need info how to skip doing one line when it is not allowed.
class A;
class B {
public:
// ...... some constructors, functions and destructor.
void add(A *a) {
// .. adds to both containers.
};
void remove(A *a) { // I need to remove from both containers at most of the times
a_container.erase(a);
a->b_container.erase(this); // PROBLEM(!!): after doing std::move(b_container) I shouldn't do this! How to check is b_container moved?
};
private:
std::_______<A*> a_container; //type of container is not important
};
class A {
friend class B;
public:
// ...... some constructors, functions and destructor.
A(A && a) :
b_container(std::move(a.b_container)) {
//..
for (B *b : b_container) {
b->add(this); //adds to B's connected to the old instance
a.remove(*b); //I need somehow to disconect old B's from pointer of moved A.
}
};
void add(B & b) {
b.add(this);
};
void remove(B & b) {
b.remove(this);
};
private:
std::_______<B*> b_container; //type of container is not important
//...
};
Is there any way I can check is std::move done on some STL container?
The std::move template does not move anything, it is only
obtains an rvalue reference to its argument and converts it to an xvalue.
If the code similar to b_container(std::move(a.b_container))
is compiled then the std::move
"works" and the b_container
has a move constructor and the move constructor moves internals of the object specified as the parameter. Otherwise code is not compilable. The following example is not compilable due to missing move constructor. Here it is on coliru.
#include <utility>
class B {
public:
B() = default;
B(B &&) = delete;
};
int main() {
B b0;
B b1(std::move(b0));
return 0;
}
Summarizing above text. std::move
"works" always.
The state of a moved object is unspecified. Link#00 and Link#01 explain this behavior.
Is there any way for B to know that old A's container is moved and it shouldn't access it?
There is no way to check either the old container is moved or not, i.e. to check it is state. But it is possible to access it, for instance, to call the std::vector::empty
method, because the object is valid. See this link for explanations.