1. ホーム
  2. c++

[解決済み] 私のクラスでスワップ機能を提供するには?

2023-02-27 13:10:06

質問

私の swap を有効にする方法はありますか?

1) メンバー swap . は std::swap は SFINAE のトリックを利用して、メンバー swap .

2)フリースタンディング swap を同じ名前空間の中に置く。

3) 部分的な特殊化である std::swap .

4) 上記すべて。

ありがとうございました。

EDIT:私の質問を明確に表現していなかったようです。基本的に、私はテンプレートクラスを持っており、私はそのクラスのために書いた(効率的な)スワップメソッドを使用するためにSTLアルゴリズムが必要です。

どのように解決するのですか?

  1. は、適切な を使用します。 swap . ライブラリのコードを書くときに、ADL(引数依存参照)を有効にしたい場合は、このように書きます。 swap . また、これはSFINAEとは関係ありません。
// some algorithm in your code
template<class T>
void foo(T& lhs, T& rhs) {
    using std::swap; // enable 'std::swap' to be found
                    // if no other 'swap' is found through ADL
    // some code ...
    swap(lhs, rhs); // unqualified call, uses ADL and finds a fitting 'swap'
                    // or falls back on 'std::swap'
    // more code ...
}

  1. ここでは、適切な方法で swap 関数を提供する適切な方法です。
namespace Foo {

class Bar{}; // dummy

void swap(Bar& lhs, Bar& rhs) {
    // ...
}

}

もし swap が今1)のように使われると、あなたの関数が見つかります。また、どうしても必要な場合はその関数をフレンドにしたり、メンバーである swap を提供することもできます。

// version 1
class Bar{
public:
    friend void swap(Bar& lhs, Bar& rhs) {
    // ....
    }
};

// version 2
class Bar{
public:
    void swap(Bar& other) {
    // ...
    }
};

void swap(Bar& lhs, Bar& rhs) {
    lhs.swap(rhs);
}

...

  1. 明示的な特殊化ということですね。部分的というのはやはり別のもので、また、関数では不可能で、構造体/クラスのみです。このように、特殊化することができないので std::swap をテンプレートクラスに対して特殊化することはできませんので があります。 を使用して、名前空間に自由な関数を提供します。言ってみれば、悪いことではありません。さて、明示的な特殊化も可能ですが、一般的には 関数テンプレートを特殊化することはありません。 :
namespace std
{  // only allowed to extend namespace std with specializations

template<> // specialization
void swap<Bar>(Bar& lhs, Bar& rhs) noexcept {
    // ...
}

}

  1. 1)は2)や3)とは別物なので、ダメです。また、2)と3)の両方を持っていると、2)の方がしっくりくるので、常に2)が選ばれることになります。