我正在努力测试我的容器包装器是否正确实现UREF。我能想到的唯一明显的方法是尝试找出一种检测对象是否已移动的方法。
是否有一种很好的测试方法来确保未复制对象?还是有另一种测试我想要的方法?我希望不需要修改要测试的类的解决方案。因为其中有几十个。
您能否提供有关您拥有的内容的更多信息?就像您的容器是什么一样,您的使用方式,可以修改或不修改它。也许您可以在不修改容器的情况下进行测试,而是通过使用特殊的容器元素类型 - 跟踪副本和移动。
几个不同的容器和一些独立的模板功能。通常,它是围绕STL库类型的包装器,例如Deque,List,Map,Set等。
是否有一种很好的测试方法来确保未复制对象?
您可以尝试以下检查:
实时演示
#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明确移动的,因此复制率无法在这里工作。
P.S。另一种方法是检查生成的汇编代码。例如,MSVC上的/fa编译器选项或gcc上的-s。
您可以通过特殊功能来标记感兴趣的地方:
__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
在构造对象时,将设置为false
的布尔字段。在移动构造函数和移动分配运算符中,将true
分配到要移动的对象中的该字段。