提问者:小点点

std::move对堆栈变量有意义吗


我需要创建一个大小为1024的结构列表。所以我试图通过使用移动语义来优化推入列表的操作。但是移动语义只对堆分配的内存有意义(根据我的知识)。有人能给我一个更好的办法吗。这是我的密码

#include <iostream>
#include <list>
    
struct St {
    int32_t arr[1024];
};
    
int main() {
    std::list<St> struct_list;
    for(int32_t i = 0; i < 1024; ++i) {
        St st; // stack allocated and memory gets deallocated after each loop
        std::cout << &st << std::endl;
        struct_list.emplace_back(std::move(st)); // I feel std::move doesn't make any sense here even if I implement move constructor, still data gets copied into the std::list which is allocated in heap, so not efficient.
        std::cout << &struct_list.back() << "\n" << std::endl;
    }
        
    return EXIT_SUCCESS;
}

共2个答案

匿名用户

给定的当前定义:

struct St {
    int32_t arr[1024];
};

从技术上讲,移动和复制这两个结果对于的这个特定定义是相同的。

但是,从语义上来说,在完成移动时标记是有意义的,而且无论如何都会被销毁。例如,如果您以后决定将的定义更改为如下内容:

struct St {
    std::vector<int32_t> vec;
};

然后,它将产生不同向量数据成员将被移动而不是复制。

简而言之,我的建议是关注移动操作的语义即,移动对象是否有意义?好吧,如果你无论如何都要处理这个对象,那么它很可能会处理。

匿名用户

如果您想要升级到C++17,您可以使用emplace_back的返回值,以便首先将它添加到列表中,然后填充它。您可以(如果默认为可构造的)首先emplace_back一个新实例,然后使用获取它并填充它。

堆栈分配和释放并不昂贵,尤其是对于pod。重要的是你对它所做的逻辑。

关于移动,对于本例,std::move将执行与复制相同的操作,因此不,您不需要它。但是,如果这是一个数组,则std::move将允许您将字符串从一个数组移动到另一个数组。

相关问题