2015-03-27 2 views
1

Есть ли способ проверить, является ли std :: move выполненным на каком-нибудь контейнере STL?Проверьте, выполняется ли std :: move на контейнере

У меня есть два типа классов (скажем, A и B), они хранят (некоторые) экземпляры другого класса во внутреннем контейнере. Если экземпляр A хранит экземпляр B в его контейнере, этот экземпляр B должен содержать тот же экземпляр A в его контейнере.

A может видеть частные методы B (B имеет его как друга), но мне нужно реализовать конструктор перемещения на B. Поскольку B может видеть внутренний контейнер обоих, я реализовал B, все это добавляет и удаляет для обоих классов ,

Проблема:
Мне нужно реализовать механизм перемещения для A и использовать stl :: move на этом контейнере. После того, как контейнер перенесен в новый экземпляр A, единственный способ уведомить B отряда старого класса - это метод, который использует B и старый контейнер A, и делает удаление для обоих классов.
Есть ли способ, чтобы B знал, что старый контейнер A перемещен, и он не должен его принимать?
Он работает без проверки, но поскольку класс не определил состояние после std :: move, я не должен вызывать :: remove() на нем (профессор говорит, что это ошибка).
Обратите внимание: это моя домашняя проблема, поэтому я не хотел бы получать незаконную помощь в решении полной проблемы, а только часть проверки согласованности объекта, чтобы пропустить вызов ее функций после ее перемещения.

EDIT: добавленный пример.
ВАЖНО:
1) Я должен использовать std :: move. Я уже знаю простой способ сделать все в while-loop, используя итераторы. Но std :: move явно требуется.
2) Этот фрагмент предназначен для понимания моей проблемы. Будучи студентом, я бы хотел решить это самостоятельно, мне нужна информация только о том, как пропустить одну строку, если она не разрешена.

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 
    //... 
}; 
+0

Вы должны попытаться составить короткий пример кода, который показывает, что вы пытаетесь сделать. Описание немного свернуто. –

+0

Благодарим за предложение. Я добавил код. – tbukic

+0

Мне довольно сложно дать только намек, потому что этот дизайн кажется ошибочным, и логика должна быть переделана. Например: в 'A (A && a)' вы используете 'a.remove (* b);', что для меня мало смысла, также это отличается от 'A :: remove', чем вы показали, потому что показан один из них: A: : remove (A *) ', а вызываемый -' A :: remove (B) ', если нет пути преобразования. – luk32

ответ

0

Есть ли способ, что я могу проверить, станд :: ход делается на какой-то контейнер STL?

std::move шаблон ничего не двигается, только

получает ссылку RValue в качестве аргумента и преобразует его в xvalue.

Если код похож на b_container(std::move(a.b_container)) компилируется затем в std::move «работает» и b_container имеет конструктор двигаться и двигаться конструктор перемещает внутренностей объекта, заданного в качестве параметра. В противном случае код не подлежит компиляции. Следующий пример не компилируется из-за отсутствия конструктора перемещения. Here находится на coliru.

#include <utility> 

class B { 
public: 
    B() = default; 
    B(B &&) = delete; 
}; 

int main() { 
    B b0; 
    B b1(std::move(b0)); 
    return 0; 
} 

Подводя итоги над текстом. std::move «работает» всегда.

Состояние перемещенного объекта не определено. Link#00 и Link#01 объясните это поведение.

Есть ли какой-либо способ для B знать, что контейнер старого A перемещен, и он не должен к нему обращаться?

Невозможно проверить, перемещен ли старый контейнер, или нет, т. Е. Проверить его состояние. Но к нему можно получить доступ, например, для вызова метода std::vector::empty, поскольку объект действителен. Для пояснений см. this link.

+0

Thanx, в вашей последней ссылке (и из документации на C++) Я вижу, что состояние объектов недействительно, но неизвестно, поэтому я не могу перейти к вызову даже простых функций. Спасибо за широкую литературу, но это все еще не решает мою проблему. – tbukic

+0

@tbukic мой ответ дает ответы на ваши вопросы. Вы писали: «Я бы хотел решить это самостоятельно». Насколько я понял, вам нужны только ответы на вопросы и нет готового решения проблемы. – megabyte1024

+0

Вы правы («проблема», в последнем комментарии, я имел в виду «найти способ пропустить линию, когда это может быть проблематично»: D). И снова - спасибо. =) На ваших ссылках я узнал, что мой код (если контейнерный класс все еще находится в правильном состоянии) будет нормально работать без каких-либо изменений, но из (цветных) частей из вашей последней ссылки и моих профессоров советует, я пришел к выводу, что было бы лучше избегать использования переадресованных, поэтому для каждого случая я реализовал его более уродливым, но более безопасным способом. – tbukic

Смежные вопросы