使用宏来专门化std :: swap

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用宏来专门化std :: swap相关的知识,希望对你有一定的参考价值。

所以,我有一个宏。

// swap_specialize.hpp
#include <algorithm>

#ifndef STD_SWAP_SPECIALIZE
#define STD_SWAP_SPECIALIZE( CLASSNAME )            
    namespace std {                                 
    template<> inline                               
    void swap( CLASSNAME & lhs, CLASSNAME & rhs )   
    { lhs.swap(rhs); } }
#endif

那我就上课了

// c.hpp
#include <vector>
#include "swap_specialize.hpp"
class C
{
    public:
        C();

        void swap(C& rhs)
        {
            data_.swap(rhs.data_);
        }
        C& operator=(C rhs)
        {
            rhs.swap(*this);
            return *this;
        }
    private:
        std::vector<int> data_;
}

STD_SWAP_SPECIALIZE(C)

以这种方式使用宏来专门化std :: swap遵循编码约定吗?

答案

我会说如果提高可读性就没关系。判断自己。只是我的两分钱:专业化std::swap并不是真正做到这一点的正确方法。考虑这种情况:

my_stuff::C c, b;
// ...
swap(c, b);
// ...

如果你没有完成std::swap或类似的东西,这将找不到using std::swap。您应该在C的命名空间中声明自己的交换:

void swap(C &a, C &b) {
  a.swap(b);
}

现在,这也适用于上述情况,因为参数依赖查找在类的命名空间中搜索。代码交换类型未知的通用事物应该像这样:

using std::swap;
swap(a, b);

无论类型如何,这将使用最佳匹配交换,如果在std::swap的命名空间中没有更好的匹配,则回退到a。对std::swap的调用进行硬编码会减少对不专门化std::swap的类型的过短,而是决定在其命名空间中提供自己的交换。

这在另一方面是优越的:想象一下qazxsw poi是一个模板。在这种情况下,你无法专攻qazxsw poi。但只是定义自己的交换,这非常好。

C

这就是如何实现std::swap和其他类的交换的方式。

另一答案

我不认为它会给你带来太大的收获。对于非模板类,它可以为您节省很少的行。对于模板类,当你想要专门化(即所有template<typename T> void swap(C<T> &a, C<T> &b) { a.swap(b); } )时,它就行不通。

另一答案

假设你正在使用std::string用于其他许多类,我认为这是完全合理的。毕竟,拥有一系列更具可读性

T

比无限扩展代码。此外,如果STD_SWAP_SPECIALIZE()的扩展稍微大一些,那么宏定义会在需要更改时在一个地方为您提供代码。 (因为模板定义在你的例子中非常小,所以它可能是一个没有实际意义的点)。

以上是关于使用宏来专门化std :: swap的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 中调用 std::swap 时的 std::bad_function_call

使用std::lock 和 std::unique_lock来起先swap操作

使用 std::vector::swap 方法在 C++ 中交换两个不同的向量是不是安全?

使用零大小数组的 std::swap() 编译错误?

std::thread::swap 的目的是啥?

将 std::iter_swap 用于 std::optional