是否可以使用宏来专门化std :: swap?

rlb*_*ond 2 c++ macros coding-style

所以,我有一个宏.

// 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
Run Code Online (Sandbox Code Playgroud)

那我就上课了

// 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)
Run Code Online (Sandbox Code Playgroud)

这样做风格上是不好的?这是代码味道吗?或者这是一个好的做法?

Joh*_*itb 6

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

my_stuff::C c, b;
// ...
swap(c, b);
// ...
Run Code Online (Sandbox Code Playgroud)

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

void swap(C &a, C &b) {
  a.swap(b);
}
Run Code Online (Sandbox Code Playgroud)

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

using std::swap;
swap(a, b);
Run Code Online (Sandbox Code Playgroud)

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

这在另一方面是优越的:想象C是一个模板.你不能专注std::swap于这种情况.但只是定义自己的交换,这非常好.

template<typename T>
void swap(C<T> &a, C<T> &b) {
  a.swap(b);
}
Run Code Online (Sandbox Code Playgroud)

这也是交换std::string和其他类的实现方式.