2016-05-28 4 views
-1

T1T2の2種類があるとします。メンバーコンテナに移動専用のクローン可能なタイプのコンストラクタをコピーする

T1は、以下の事実を除き、重要ではありません。

  • それがコピーされていない構成可能、それは我々が作成した署名T1 copy(T1 const& orig)、優れた機能を持って移動コンストラクタ
  • を持って
  • コピー。

T2では、以下のクラスに簡素化することができます。

// T2.h 
class T2 { 
public: 
    T2() { /* initializes the vector with something */ } 
    T2(T2 const& other); 
private: 
    std::vector<T1> v; 
} 

// T2.cpp 

T2::T2(T2 const& other) : ... {} 

あなたが唯一の省略記号部分に、またはグローバルスコープに書き込むことができれば、どのように、このメソッドを実装しますか?

簡単な実世界のユースケース - 部分は、現実世界の制限である「あなたは、中括弧の間に何かを書き込むことはできません」と仮定:

  • T1std::unique_ptr<anything>
  • copyではstd::make_unique
  • ですanythingにはコピーコンストラクタがあります

また、次の2つの追加要件があります。実装:

  • パフォーマンス。コピーコンストラクタの本体にループforを持つ単純な実装よりも(かなり)遅くすべきではありません。
  • 可読性。問題の背後にある全体のポイントは、単純なforループ(例えば、2つ以上のメンバーベクトルを持つT2を想像する)よりも明確で清潔な何かをすることです。

とオプションが、機能があると便利:簡単に他のコンテナ

  • に一般化だ

    • 何かで動作する何かがちょうど一般的な

    Aだ

  • 何かをイテレータ明確化:質問は、グローバル関数std::vector<T1> copy_vec(std::vector<T1> const& orig)で簡単に解くことができます。その関数をT2.cppの匿名の名前空間に置くこともローカルにするでしょうが、私はその可読性に反すると主張しますが、forループよりも良くないと思います。コピーコンストラクターが実装ファイルになく、ヘッダーにインライン展開されている場合は、明らかに悪い解決策です。

    だから私の質問の言い換えは、次のとおりです。

    • は、すでに私は含めることができます似たような実装、ありますか?
    • 何もない場合、なぜですか?私はすべてのコーナーケースについて考えていると言っているわけではありませんが、これはおそらく素敵な一般的な方法で実装できるものだと思います。unique_ptrのおかげで十分です。素朴なループと間違っ
  • +0

    'other.v'をとり、コピーした' vector'を返す関数を作ることができますか? –

    +0

    はい、私は私の質問で言及しました。しかし、実際には、コピーコンストラクタを持たない型を含むコンテナをコピーする既存の機能はありません。 – Dutow

    +0

    それはタイプミスだったので、私は 'T1'の代わりに' T2'を書きました。 – Dutow

    答えて

    1

    何もありません:

    v.reserve(other.v.size()); 
    for (auto& elem : other.v) { 
        v.push_back(copy(elem)); 
    } 
    

    たくさん読めると最適です。

    私は現代を推測するが、巧妙な解決策はrange-v3を使用することで:

    T2(T2 const& other) 
    : v(other.v | view::transform(copy)) 
    { } 
    

    私は、追加の複雑さが、メーリングリストを正当化するためにループよりも十分に優れていわかりません。

    +0

    例に基づいて、 'range-v3'は有望に見えます、はい。コードに応じて複雑さに反すると私は主張しますが、変換バージョンの意図ははるかに綺麗で読みやすくなります。 – Dutow

    +0

    私は最初のテストに基づいてforループまたは私のバージョンよりもはるかに高速ですが、これは間違いなく面白いです、私は明日の理由を理解しようとします。 – Dutow

    +0

    多くのテスト:コンパイラ、フラグ、およびビルドタイプ(単一のTUまたは標準)によって、実行時間の差は-5〜+ 20%です。 (-O2を使用して統合ビルドを使用してコンパイルした場合のforループよりも優れています)。これはおそらく、よりシンプルなソースコードや他の可能性については良いトレードオフでしょう。 – Dutow

    関連する問題