2016-09-15 3 views
11

私の関数で出力引数を避けようとしています。古い機能は次のとおりです。関数はベクトルで作られたタプルを返します

void getAllBlockMeanError(
    const vector<int> &vec, vector<int> &fact, vector<int> &mean, vector<int> &err) 

ここvecが入力引数で、factmeanerrは出力引数です。私は1つのタプルにグループ出力引数に試してみました:それは私にはきれいに見える

tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec); 

tuple< vector<int>, vector<int>, vector<int> > 
            getAllBlockMeanErrorTuple(const vector<int> &vec) 
{ 
    vector<int> fact, mean, err; 
    //.... 
    return make_tuple(fact, mean, err); 
} 

は今、私は新しい関数を呼び出すことができます。質問がありますが、tie(fact, mean, err)の等価割り当てはどのように機能しますか?深いコピーや移動をしますか? fact以降、meanerrgetAllBlockMeanErrorTupleの内部が破壊されますので、深いコピーではなく移動していることを願っています。

+0

私は肯定的ではないんだけど、私は書かれて、それはベクトルをコピーすると思います。ベクタを 'make_tuple()'に移動すると、ベクタは移動する必要があります。 – Andy

+5

私は 'struct Result {vector ファクト;ベクター平均;ベクターエラー; }; getterのより良い命名をするためにタプルの代わりに。 – Jarod42

答えて

12

あなたがそう

std::tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec) 

factmean、およびerrを移動し、割り当てる必要があり、署名は一時的なもので、要素が移動の対象である、tuple< vector<int>, vector<int>, vector<int> >で機能します。ここで

は、あなたが自分自身(demo)を参照するためのサンプルプログラムです:

#include <iostream> 
#include <vector> 
#include <tuple> 

struct A 
{ 
    A() = default; 
    ~A() = default; 
    A(const A&) 
    { 
     std::cout << "Copy ctor\n"; 
    } 
    A(A&&) 
    { 
     std::cout << "Move ctor\n"; 
    } 
    A& operator=(const A&) 
    { 
     std::cout << "Copy assign\n"; 
     return *this; 
    } 
    A& operator=(A&&) 
    { 
     std::cout << "Move assign\n"; 
     return *this; 
    } 
}; 

std::tuple<A, A> DoTheThing() 
{ 
    A first; 
    A second; 
    return std::make_tuple(first, second); 
} 

int main() 
{ 
    A first; 
    A second; 
    std::tie(first, second) = DoTheThing(); 
} 

出力:

コピー
コピーCTOR
移動CTOR
移動が

を割り当てる割り当て

この関数は、tupleを返すためのベクトルのコピーを作成しなければならないことに注意してください。あなたはstd::make_tuplestd::moveに要素をしたいことがあります。C++ 17の構造化されたバインディングで、あなたがすべてでstd::tieを使用して忘れることができ、そしてautoにもっと傾くこと

return make_tuple(std::move(fact), std::move(mean), std::move(err)); 

Here's the same example as above, but with std::move used in make_tuple

注意(おかげで、@ Yakk):C++ 17打ち鳴らすための標準(3.8.0)とGCC(6.1.0)の初期の実装はまだそれをサポートしていない

auto[fact, mean, err] = getAllBlockMeanErrorTuple(vec); 

は、しかし、C言語でいくつかのサポートがあるようですLANG 4.0.0:

移動CTOR
移動CTOR

彼らことを示す:Demo(おかげで、@Revolver_Ocelot)

あなたはに構造化されたバインディングの変更と出力があることに気づくでしょう追加の移動操作を節約するcopy-elisionを活用します。

+1

'自動[事実、平均、エラー] = getAllBlockMeanErrorTuple(vec); ' – Yakk

+1

@ヤク:そのC++ 17ではないですか? – AndyG

+0

はい、私は言及する価値があると主張します。 – Yakk

11
std::tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec); 

移動割り当てを行います。

しかし、コピーを行うだろうコメント

return make_tuple(fact, mean, err); 

に述べたように、あなたがいることを解決することがあります。

return make_tuple(std::move(fact), std::move(mean), std::move(err)); 
+0

少なくともC++の構造化バインディングに言及してください!私たちはここから数ヶ月離れています! (ここでは限定値) – Yakk

+0

ありがとうJarod42。 –

関連する問題