2017-07-09 28 views
1

我有一个问题,我想在单个容器类中存储结构向量。利用C++中的移动语义

问题是,当为这些向量创建这个容器时,我浪费资源,因为向量被复制;没有移动。为什么临时返回的资源create()没有转移到主函数中的局部变量master_data

我假定将工作

示例代码被呈现以下(并且在coliru HERE):

#include <stdio.h> 
#include <vector> 
#include <stdlib.h> 

// Specific data struct 
typedef struct DataA { 
    DataA(): a(rand()), 
      b(rand()) {} 
    int a,b;  
} DataA; 

// Another specific data struct 
typedef struct DataB { 
    DataB(): c(rand()), 
      d(rand()) {} 
    int c,d; 
} DataB; 

// Container of all relevant data 
typedef struct Master { 
    Master(const std::vector<DataA> &a, const std::vector<DataB> &b) : data_a(std::move(a)), data_b(std::move(b)) {} 
    Master(const Master &rhs) : data_a(std::move(rhs.data_a)), data_b(std::move(rhs.data_b)) {} 

    std::vector<DataA> data_a; 
    std::vector<DataB> data_b; 
} Master; 


Master create() { 
    std::vector<DataA> data_a(10); 
    std::vector<DataB> data_b(10); 

    printf("data_a address inside create() : %p\n", (void*)data_a.data()); 
    printf("data_b address inside create() : %p\n", (void*)data_b.data()); 

    return {data_a, data_b}; 
} 


int main() 
{ 
    Master master_data(create()); 

    printf("data_a address outside create() : %p\n", (void*)master_data.data_a.data()); 
    printf("data_b address outside create() : %p\n", (void*)master_data.data_b.data()); 
    return 0; 
} 
+1

的概念被称为“移动**语义**“,而不是”移动原理图“。 –

+0

__Paste__你想问的代码,不要链接到它们。还提供[mcve]和明确的问题陈述。 “这有用吗?”并不是一个明确的问题陈述,“行x是否具有Y的时间复杂性?”是。 –

+0

@PserserBy:我做了编辑改进问题。 – ELEC

回答

1

这里:

Master(const Master &rhs) : data_a(std::move(rhs.data_a)), data_b(std::move(rhs.data_b)) {} 

的参数是恒定,这防止它们被移动,因为它们是不可变的。

尝试使用这样的事情,而不是:

Master(Master&& rhs) : data_a(std::move(rhs.data_a)), data_b(std::move(rhs.data_b)) {} 

在那里我放弃了const&&增强您的参数。

同样的构造,你会怎么做:

Master(std::vector<DataA>&& a, std::vector<DataB>&& b) : data_a(std::move(a)), data_b(std::move(b)) {} 

最后,但并非最不重要的,你应该修改你的创造功能,像这样(否则你将得到有关无法绑定编译错误):

Master create() { 
    ... 
    return {std::move(data_a), std::move(data_b)}; 
} 
0

你的构造:

Master(const std::vector<DataA> &a, const std::vector<DataB> &b); 

接受ab参数作为常量引用。你必须定义它接受右值引用如下:

Master(std::vector<DataA>&& a, std::vector<DataB>&& b); 

但在这种情况下,你必须表明data_adata_bcreate()函数内可以移动:

Master create() { 
    std::vector<DataA> data_a(10); 
    std::vector<DataB> data_b(10); 

    printf("data_a address inside create() : %p\n", (void*)data_a.data()); 
    printf("data_b address inside create() : %p\n", (void*)data_b.data()); 

    return { std::move(data_a), std::move(data_b) }; 
}