2017-07-09 8 views
1

個々のコンテナクラス内に構造体のベクトルを格納したいという問題があります。C++での移動セマンティクスの活用

問題は、これらのベクトル用にこのコンテナを作成すると、ベクターがコピーされるためにリソースが浪費されることです。移動されません。一時的なリソースがcreate()によって返されるのはなぜですか?main関数のローカル変数master_dataに転送されませんか?

Iが働くことになると想定

サンプルコードを以下に示す(および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

コンセプトは "と呼ばれていますmove ** semantics ** "、" move schematics "ではありません。 –

+0

__Paste__あなたが尋ねたいコードは、リンクしないでください。また、[mcve]と明確な質問文を提供してください。 "これは機能しますか?"明確な質問文ではない、「x行はYの時間複雑さを持っていますか?です。 –

+0

@PasserBy:質問を改善するために編集しました。 – 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); 

はを受け入れます3210およびbパラメータを定数参照として使用します。あなたは、次のよう右辺値参照を受け入れるようにそれを定義する必要があります。

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

をしかし、この場合には、あなたはcreate()関数内data_adata_bが移動できることを示す必要があります:

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) }; 
} 
関連する問題