最简洁的方法来禁用复制和移动语义

Lin*_*gxi 17 c++ copy move-semantics c++11

以下肯定有效,但非常繁琐:

T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
Run Code Online (Sandbox Code Playgroud)

我正试图发现最简洁的方式.以下工作会吗?

T& operator=(T) = delete;
Run Code Online (Sandbox Code Playgroud)

更新

请注意,我选择T& operator=(T)而不是T& operator=(const T&)T& operator=(T&&),因为它可以同时满足两个目的.

Hol*_*Cat 25

根据这张图表(Howard Hinnant):

喵

简洁的方法是=delete移动赋值运算符(或移动构造函数,但它可能会导致注释中提到的问题).

不过,在我看来,最可读的方式是=delete 拷贝构造函数和拷贝赋值运算符.

  • [霍华德图表的视频描述](http://www.youtube.com/watch?v=vLinb2fgkHk&t=13m22s) (6认同)
  • 我还建议只使用赋值运算符,而不是移动c'tor.明确删除c'tor可以搞乱RVO (5认同)
  • 注意红细胞; 那些是标准设计中的缺陷和问题. (5认同)
  • 我的指导方针是[永远不要删除移动成员.](/sf/answers/2717412491/) (5认同)
  • @Lingxi - 不会影响其他特殊成员函数的生成.你仍然可以获得一个复制/移动c'tor. (2认同)

Vit*_*meo 5

您可以编写一个简单的struct并从中继承:

struct crippled
{
    crippled() = default;

    crippled(const crippled&) = delete;
    crippled(crippled&&) = delete;

    crippled& operator=(const crippled&) = delete;
    crippled& operator=(crippled&&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

用法:

struct my_class : crippled
{

};

int main()
{
    my_class a;
    auto b = a; // fails to compile
}
Run Code Online (Sandbox Code Playgroud)

  • 那将是 boost::noncopyable (http://www.boost.org/doc/libs/1_65_0/libs/core/doc/html/core/noncopyable.html) (7认同)
  • 我相信Boost有一个这样的类。继承它而不是自己滚动会更透明(尽管如果这是“唯一”用途,则不值得在项目中使用 Boost)。 (2认同)

ein*_*ica 5

请不要试图寻找“最简洁的方式”来编写一段代码。

如果没有一种明显的形式来表达同样非常简洁的东西——不要试图用语言律师的方式少写几个字符。为什么?想想阅读您代码的人:如果您需要查阅标准来实现您的代码执行您希望它执行的操作,那么您代码的读者也会如此。只是他们不会知道你想要实现什么;所以他们不会查阅标准;所以他们会对你的代码的作用感到困惑。或者 - 有些人会得到它,有些人则不会。*

在你的情况下,如果你做了这些删除的子集,或者使用一些其他“聪明”的技巧 - 作为一个阅读你的代码的人,我很可能不会明白,没有注意到你实际上正在尝试获取所有副本和删除移动语义。我会感到困惑,以为你在尝试做其他事情。事实上,如果我是你,我什至会考虑添加一条评论:

/* Disabling copy and move semantics because XYZ */
T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
Run Code Online (Sandbox Code Playgroud)

这更加“乏味”,但会让你未来的读者绝对清楚你的意图/动机。

还有一个问题是“XYZ”原因到底是什么。有些人会认为没有充分的理由删除移动成员,而且这样做通常是一个坏主意。C++ 杰出人物 Howard Hinnant对于此事有这样的说法。

* - 我在这里阐述的原则的一个变体。

  • 我认为是的,只要它不违背表现力。`boost::noncopyable` 是实现这两个 IMO 的一个很好的例子 (3认同)
  • 您假设最简洁的方式表达能力较差,但情况不一定如此。如果能够在保持精确的情况下简洁地表达意图,那么意图就会更加清晰。 (2认同)