隐式特殊函数:它们什么时候会是病态的?

Implicit special functions: when would they be ill-formed?

在 C++11 的 ISO 国际标准 中,总结了 C++ 2003 和 C++ 2011 之间的差异。其中一个区别是:

[diff.cpp03.special]

Change: Implicitly-declared special member functions are defined as deleted when the implicit definition would have been ill-formed.

Rationale: Improves template argument deduction failure.

Effect on original feature: A valid C++ 2003 program that uses one of these special member functions in a context where the definition is not required (e.g., in an expression that is not potentially evaluated) becomes ill-formed.

我看不出这种特殊函数在什么情况下会格式错误,以及它如何破坏 SFINAE。所以我的问题归结为:

struct NonCopyable {
  NonCopyable() {}
private:
  NonCopyable(const NonCopyable &);
};

struct S {
  NonCopyable field;
} s;

int main() {
  return sizeof S(s);
}

这里,NonCopyable是non-copyable,但是由于显式提供了拷贝构造函数,所以没有创建隐式拷贝构造函数。

对于S,用户没有提供拷贝构造函数,所以创建了一个隐式拷贝构造函数。此复制构造函数将复制 NonCopyable field 字段,即 non-copyable,因此复制构造函数将是 ill-formed.

main中,取copy-constructedS对象的大小。这需要 S 的复制构造函数,但实际上并没有调用它。

在 C++03 中,这是有效的。复制构造函数将是 ill-formed,但由于从未进行过复制,所以没关系。

在 C++11 中,这是无效的。复制构造函数被标记为已删除,因此甚至不能用作 sizeof.

的操作数

这允许元编程检测类型是否可复制,这在 C++03 中是不可能的。

如果你想要一个具体的例子,std::pair 通常很容易复制,但是如果其中一个成员是 std::unique_ptr,unique_ptr 则不允许从左值复制,所以它将是 ill-formed:所以 std::pair 默认的左值复制操作被自动删除。