1

タイトルがすべてを物語っています。

最初のケース f(const X&) は古き良き const 参照パラメーターです。

ただし、変更可能な参照パラメーターを使用する場合、常に X&& を使用しないのはなぜでしょうか? このようにして、クライアント コードは、f() が使用法を指示するのではなく、一時または通常の左辺値を使用できます。

編集:私の側のずさんさ、申し訳ありません。つまり、fc(const X&) と fm(X&&) が与えられた場合、fm(X&) は必要ですか?

編集: 例: ステートレス デコレータを使用してパラメーターとして渡します。

class Base64Writer: public Writer {
public:
  Base64Writer(Writer& w): w_(w) {}
private:
  virtual void doWrite() override;
  Writer& w_;
}

void func(Writer&& w) { w.doWrite(); }

// to be called as
Writer wr = ...;
func(Base64Writer(wr));
4

3 に答える 3

2
  • 質問するつもりなら、3 つのオーバーロードすべてを同時に持つことは論理的ですか?

    ほとんどの場合、それは悪い考えです。オーバーロードされた関数のセマンティックが互いに矛盾するためです。1 つは引数を変更しないことを約束し、もう 1 つはそのような約束をしません (暗黙のうちに引数を変更すると言っています!)。このようなオーバーロードされた関数のユーザーは、 が異なるだけで混乱しますconst

    これらのオーバーロードを同時に持つことは理にかなっています:

    void process(std::vector<int> const&);
    void process(std::vector<int> &&);
    

    しかし、上記の 2 つに加えて 3 番目のものは、私にはあまり意味がありません。

    void process(std::vector<int> &); //contradicts the first overload
    

    混乱を招き、コードを読みにくくするだけです。このセマンティックが必要な場合は、関数に別の名前を選択してください!

  • 質問する場合は、どれを使用する必要がありますか (ただし、すべてを同時に使用する必要はありません)。

    セマンティックに依存すると思います。パラメータが入力および/または出力パラメータとして動作する場合、f(X&)意味があります。パラメーターが単なる入力パラメーターである場合f(X const&)は、意味があります。この場合、f(X&&)パフォーマンス上の利点を得るために追加で定義することもできます!

于 2013-01-19T09:17:43.340 に答える
2

絶対!

たとえば、引数として渡されたコンテナーを操作するときは常に必要です。

実際、これら 3 つすべてが必要な場合があります。たとえば、次のように比較してください。

vector<int> append_if_not_ends_with(vector<int> const &original, int x)
{
    vector<int> v(original);
    if (v.empty() || v.back() != x)
    { v.push_back(x); }
    return v;
}

vector<int> &append_if_not_ends_with(vector<int> &v, int x)
{
    if (v.empty() || v.back() != x)
    { v.push_back(x); }
    return v;
}

vector<int> append_if_not_ends_with(vector<int> &&original, int x)
{
    vector<int> v(std::move(original));
    if (v.empty() || v.back() != x)
    { v.push_back(x); }
    return v;
}

3 つのオーバーロードがすべてある場合は、必要のないときにベクターの内容をコピーすることを避けることができます。

vector<int> v1;
vector<int> const &v2 =
    foo ? append_if_not_ends_with(v1) :
    bar ? append_if_not_ends_with(static_cast<vector<int> const &>(v1)) :
          append_if_not_ends_with(vector<int>());
于 2013-01-19T09:21:12.220 に答える
1

実際に値渡しができること、そして c++11 でのこのプラクティスは、実際にはf(X&&).

イモ:

  • f(const X &)要素から読み取るだけでよい場合に使用します。
  • f(X)渡されたオブジェクトの所有権を取得する必要がある場合に使用します。関数の呼び出し元は、必要に応じてf( std::move(something))or を実行できf(something)ます。
  • f(X&)渡されたオブジェクトを変更する必要がある場合に使用します。
于 2013-01-19T10:38:11.923 に答える