3

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
    //...
};
mr.engineer
  • 187
  • 12
  • You should try to put together a short example of code that shows what you're trying to do. The description is a bit convoluted. – Retired Ninja Mar 27 '15 at 06:45
  • To me it's pretty impossible to give just a hint, because this design seems faulty and logic should be remodeled. E.g: in `A(A && a)` you use `a.remove(*b);` which makes little sense to me, also it's different `A::remove` than you shown because the one shown is `A::remove(A*)` and the called is `A::remove(B)`, unless there is some conversion path. – luk32 Mar 27 '15 at 07:49
  • Are you sure, could you specifie the line? This code compiles and works perfectly on my compiler (correct classes contain correct ones after all operations). Only problem is that it is not theoretically OK because of the line I specified which should sometimes be skipped. If you mean that logic should be changed to do that than I understand it. Otherwise, it does OK only because of implementation that is natural and expected, but not specified. – mr.engineer Mar 27 '15 at 13:09
  • Here are the things you can do with a moved-from std::container: http://stackoverflow.com/a/7028318/576911 – Howard Hinnant Mar 27 '15 at 15:42

1 Answers1

1

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.

Community
  • 1
  • 1
megabyte1024
  • 8,482
  • 4
  • 30
  • 44
  • Thanx, on your last link (and from c++ documentation) I see that state of objects is not valid, but unknown, so I cannot proceed to call even simple functions. Thank you for the wide literature, but this still doesn't resolve my problem. – mr.engineer Mar 27 '15 at 21:24
  • @tbukic my answer gives answers to your questions. You wrote `I'd like to solve it by myself`. As far as I understood you need only answers to the questions and do not have a ready solution of the problem. – megabyte1024 Mar 27 '15 at 22:00
  • You're right (by "problem", in last comment, I've meant "finding the way of skipping the line when it could be problematic" :D ). And - thanx again. =) On your links I found out that my code (if container class is still in valid state) would run OK without any change, but from (colored) the parts from your last link and my professors advises, I concluded it would be better to stay off from using moved-from, so for every case I have implemented it in uglier, but safer way. – mr.engineer Mar 27 '15 at 22:10