如何为我的班级提供交换功能?

2022-01-07 00:00:00 swap c++ stl

在 STL 算法中启用我的 swap 的正确方法是什么?

What is the proper way to enable my swap in STL algorithms?

1) 成员swap.std::swap 是否使用 SFINAE 技巧来使用成员 swap.

1) Member swap. Does std::swap use SFINAE trick to use the member swap.

2) 同一命名空间中的独立swap.

2) Free standing swap in the same namespace.

3) std::swap 的部分特化.

4) 以上所有.

谢谢.

看起来我没有清楚地表达我的问题.基本上,我有一个模板类,我需要 STL 算法来使用我为该类编写的(高效)交换方法.

Looks like I didn't word my question clearly. Basically, I have a template class and I need STL algos to use the (efficient) swap method I wrote for that class.

推荐答案

  1. swap的正确使用.写library"的时候就这样写代码并希望在 swap 上启用 ADL(依赖于参数的查找).此外,这与 SFINAE 无关.
  1. is the proper use of swap. Write it this way when you write "library" code and want to enable ADL (argument-dependent lookup) on swap. Also, this has nothing to do with 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 函数的正确方法:
  1. Here is the proper way to provide a swap function for your class:

namespace Foo {

class Bar{}; // dummy

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

}

如果 swap 现在使用,如 1) 所示,您的函数将被找到.此外,如果您绝对需要,您可以将该函数设为好友,或者提供由自由函数调用的成员 swap:

If swap is now used as shown in 1), your function will be found. Also, you may make that function a friend if you absolutely need to, or provide a member swap that is called by the free function:

// 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. 您的意思是明确的专业化.Partial 仍然是别的东西,对于函数也不可能,只有结构/类.因此,由于您不能为模板类专门化 std::swap,您必须在您的命名空间中提供一个免费的函数.不是坏事,如果我可以这么说的话.现在,显式特化也是可能的,但通常您不想特化函数模板:
  1. You mean an explicit specialization. Partial is still something else and also not possible for functions, only structs / classes. As such, since you can't specialize std::swap for template classes, you have to provide a free function in your namespace. Not a bad thing, if I may say so. Now, an explicit specialization is also possible, but generally you do not want to specialize a function template:

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),因为它更适合.

相关文章