c++ - 测试一个对象是否已经从

标签 c++ c++11 move-semantics universal-reference

我正在测试我的容器包装器是否正确实现了 URef。我能想到的唯一明显的方法是尝试找出一种检测对象是否已 move 的方法。

是否有一种好的测试方法来确保对象未被复制?还是有另一种方法来测试我想要的东西?我更喜欢不需要修改我正在测试的类的解决方案。因为有几十个。

Could you please provide some more info on what you have? Like what is your container, how you use it, can you modify it or not, etc. Maybe you can test this without modification of your container, but rather by using special container element type - which tracks copies and moves.

几个不同的容器和一些独立的模板函数。大多数情况下,它是 STL 库类型的包装器,例如 deque、list、map、set 等。

最佳答案

Is there a good way of testing to make sure that an object was not copied?

您可以尝试以下检查:

live demo

#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
________________

请注意,在这段代码中,我使用了从左值的显式 move ,因此复制省略在这里不起作用。







附言另一种方法是检查生成的汇编代码。例如 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;

汇编代码可能如下所示:

    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   

关于c++ - 测试一个对象是否已经从,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13327198/

相关文章:

c++ - QWidget Initialization 在函数调用中的不同行为

c++ - QGraphicsView滚动问题

c++ - 类的std::thread调用方法

c++ - 如何获取我的 websocket 的服务器 IP 地址

c++ - 基于模板参数值的类型

c++ - 是否有任何有效的用例可以在现代 C++ 中使用 new 和 delete、原始指针或 c 样式数组?

c++ - 如何测试 double 值是否不为负

c++ - 对象 move 后,指向const vector 成员变量元素的指针是否保持稳定?

c++ - C++ 中的值语义和 move 语义之间有什么联系?

rust - Rust 中的 move 语义是什么?