Проверка того, был ли объект перемещен из

Я работаю над проверкой правильности реализации URef в моих контейнерах-контейнерах. Единственный очевидный способ, который я могу придумать, — это попытаться выяснить способ обнаружения перемещения объекта.

Есть ли хороший способ проверки, чтобы убедиться, что объект не был скопирован? Или есть другой способ проверить то, что я хочу? Я бы предпочел решение, которое не требует изменения классов, которые я тестирую. Потому что их пара десятков.

Не могли бы вы предоставить больше информации о том, что у вас есть? Например, каков ваш контейнер, как вы его используете, можете ли вы изменить его или нет, и т. Д. Возможно, вы можете проверить это без изменения вашего контейнера, а с помощью специального типа элемента контейнера — который отслеживает копии и перемещения.

Несколько разных контейнеров и несколько отдельных шаблонных функций. В основном это обертки вокруг типов библиотек STL, таких как deque, list, map, set и т. Д.

5

Решение

Есть ли хороший способ проверки, чтобы убедиться, что объект не был скопирован?

Вы можете попробовать следующую проверку:

живое демо

#include <boost/container/vector.hpp>
#include <iostream>
#include <ostream>
#include <vector>
#include <string>

using namespace boost;
using namespace std;

struct Test
{
bool copied;
Test()
: copied(false)
{
}
Test(const Test&)
: copied(true)
{
}
};

template<typename Container>
void check_move_constructor()
{
Container from(1);
Container to(boost::move(from));
cout << "\tmove constructor is" << (to[0].copied ? " not" : "") << " working" << endl;
}

template<typename Container>
void check_move_assignment()
{
Container from(1);
Container to;
to=boost::move(from);
cout << "\tmove assignment is" << (to[0].copied ? " not" : "") << " working" << endl;
}

template<typename Container>
void check_move(const string &name)
{
cout << name << " :" << endl;
check_move_constructor< Container >();
check_move_assignment< Container >();
cout << string(16,'_') << endl;
}

int main()
{
cout << boolalpha;
check_move< container::vector<Test> >("boost::container::vector");
check_move< vector<Test> >("std::vector");
return 0;
}

Выходы MSVC2008:

boost::container::vector :
move constructor is working
move assignment is working
________________
std::vector :
move constructor is not working
move assignment is not working
________________

Обратите внимание, что в этом коде я использовал явное перемещение из lvalues, поэтому Copy-elision здесь не может работать.







Постскриптум Другой способ сделать это — проверить сгенерированный ассемблерный код. Например, опция компилятора / FA в MSVC или -S в GCC.

Вы можете пометить достопримечательность с помощью вызова специальной функции:

__declspec(noinline) void asm_marker(int line) { volatile int i=line; };
#define ASM_MARKER asm_marker(__LINE__)

И поместите этот маркер в коде:

    ASM_MARKER;
func_of_interest();
ASM_MARKER;

Asm-код может выглядеть так:

    mov     ecx, 235                                ; 000000ebH
call    ?asm_marker@@YAXH@Z                     ; asm_marker
mov     edi, r12d
lea     rcx, QWORD PTR [rdi+rdi*4]
mov     rax, QWORD PTR vec$[rsp]
lea     r9, QWORD PTR [rax+rcx*8]
mov     rbx, QWORD PTR vec$[rsp+32]
mov     ecx, 237                                ; 000000edH
call    ?asm_marker@@YAXH@Z                     ; asm_marker
1

Другие решения

Добавьте логическое поле, для которого установлено false когда объект построен. В конструкторе перемещения и операторе присваивания перемещения назначьте true в это поле в объекте, который перемещается из.

1

По вопросам рекламы [email protected]