使用宏来覆盖移动功能界面的缺点

时间:2017-06-05 04:05:34

标签: c++ macros c++14 move-semantics

使用宏作为所有移动语义的接口有什么缺点?

我最近在类(http://stackoverflow.com/a/4782927/)中阅读了与移动相关的函数的语法,在我看来,它是相当繁琐和重复的: -

C(C&&) = default;                    // Move constructor
C& operator=(C&&) & = default;       // Move assignment operator

如果我想使用相同的实现自定义move-assignment和move-constructor,那就更脏了。 (与Copy constructor and = operator overload in C++: is a common function possible?相同的问题)

因此,我决定创建一个宏(类似交换的函数),使所有内容都在一个地方简洁。

#define MACRO_MOVE(C)                        \
C& operator=(C&& that) &  {                 \
     moveHack(this,&that);  return *this;    \
}                                            \
C(C&& that){                                 \
     moveHack(this,&that);                   \
}                                            \
static void moveHack(C* dst,C* src)

以下是用法: -

class X{
    int data=42;
    MACRO_MOVE(X){
        dst->data=src->data;
        src->data=0;
    }
};

然而,我以前没见过有人这样做过 我应该关注哪些问题?
这种方法有什么特别的缺点吗?

1 个答案:

答案 0 :(得分:0)

零规则是只有管理资源的类(如内存)才需要显式的移动/复制赋值/构造方法。

您可以将几乎所有类型的存储编写为自我管理资源。这些资源类型往往是几种不同变体之一(值指针,唯一指针,共享指针等)。

通常在移动分配时,您还需要清理现有状态。移动构建时,这不是真的。这两个实现可以共享一些代码,但通常你不希望它们。

为一些简单的资源管理类型做这种宏hackery是一个坏主意。拥有复杂的资源管理类型是一个坏主意。这个宏观hackery doens处理移动和分配是根本不同的操作。一般来说,宏只应在避免成本高昂的情况下使用。

你的宏没有增加太多效用。它做什么看起来容易出错并且很危险。如果你必须调试它,你会获得不可判断的代码。

因此有很多理由不使用该宏,很少使用它。

建筑,任务和破坏是紧密联系在一起的。赋值可以被视为破坏+建构天真,但这通常是无效的;而你的甚至没有毁灭!