C++ 删除和默认函数真实世界示例

C++ 删除和默认函数真实世界示例,c++,c++11,C++,C++11,我正在看C++11的新特性,其中一个让我困惑,因为我想不出在现实世界中使用它的方法 它是被删除和默认的函数,是否有人有它使用的真实示例,或者它只是添加了一些糖分的功能之一?用户声明的特殊成员函数并非微不足道。如果类具有任何非平凡的特殊成员函数,则该类不是POD。因此,该类型为POD: struct S { S() = default; S(int) { } }; 但这种类型不是POD: struct S { S() { } S(int) { } }; 假设我们

我正在看C++11的新特性,其中一个让我困惑,因为我想不出在现实世界中使用它的方法


它是被删除和默认的函数,是否有人有它使用的真实示例,或者它只是添加了一些糖分的功能之一?

用户声明的特殊成员函数并非微不足道。如果类具有任何非平凡的特殊成员函数,则该类不是POD。因此,该类型为POD:

struct S {
    S() = default;
    S(int) { }
};
但这种类型不是POD:

struct S {
    S() { }
    S(int) { }
};
假设我们的默认构造函数没有做任何特殊的事情,并且(或多或少)等于编译器生成的构造函数。我们可以通过编写我们自己的默认构造函数(如果我们的类有许多非静态成员,这可能会变得单调乏味)或使用
=default
语法来修复它:

struct A
{
  A() = default;
  A(const A& arg) : data(arg.data)
  {
    do_something_special();
  }

  int data;
};

当我们想要禁止使用特定的重载或模板专门化,或者仅仅是为了禁止复制(或移动)对象时,删除函数非常有用

当您想要禁止复制(即线程对象)时,通常惯用的方法是在没有实现的情况下声明私有复制构造函数(是的,或者使用boost::noncopyable)。虽然这在大多数情况下都有效,但有时您可能会遇到一些模糊的链接器错误。考虑:

struct A
{
  A() = default;

  friend void foo();

private:
  A(const A&);
};

void foo()
{
  A a;
  A b(a); // results in linker error in gcc
}

A(const A&)
删除,我们可以避免潜在的链接器错误,并使我们的意图(不允许复制)非常明确。

您可以将删除的函数用于您希望防止复制或直接实例化的类,例如(要执行get\u instance()函数的la singleton)。还可以使用delete来防止构造函数的某些变化

如果希望编译器为隐式生成的任何构造函数生成构造函数,则默认值非常有用。例如,如果创建自定义参数构造函数,编译器将不会生成默认的无参数构造函数,因此您可以要求使用default关键字为您生成它

请参见此处以获取上述示例


@Christian:如果我们只需要
结构S{S(int){},存在
S(int)
将抑制隐式声明的默认构造函数。POD的规则在C++0x/11中已经放宽,因此您的第二个示例也是C++0x/11中的POD。您还可以使用新的traits::is_pod来检查您自己,例如使用静态断言。@David:pod的规则确实已经放宽了,但是第二个
S
仍然不是pod。POD结构必须是普通类。平凡类必须具有平凡的默认构造函数。用户提供的默认构造函数并不简单。第二个
S
有一个用户提供的默认构造函数,因此不是POD。@詹姆斯:我肯定你错了。看来你是对的。但是,如果你在第二个例子中添加了一个
constexpr
,它又变成了一个POD类。James请阅读这个-,从这里我看到你的第二个例子是一个POD。构造函数与C++0x/11中的POD无关。
void foo(char c) {}
void foo(int i) = delete; // do not allow implicit int -> char conversion
struct A
{
  A() = default;

  friend void foo();

private:
  A(const A&);
};

void foo()
{
  A a;
  A b(a); // results in linker error in gcc
}