隐含的特殊功能:什么时候它们会形成错误?

YSC*_*YSC 16 c++ c++11 c++03

在ISO 国际标准 C++ 11中,给出了c ++ 2003和C++ 2011之间差异的总结.其中一个不同之处是:

[diff.cpp03.special]

更改:当隐式定义不正确时,隐式声明的特殊成员函数被定义为已删除.

理由:改进模板参数推导失败.

对原始特征的影响:在不需要定义的上下文中使用这些特殊成员函数之一的有效C++ 2003程序(例如,在无法评估的表达式中)变得格式不正确.

我没有看到这种特殊功能在哪种情况下会形成错误,以及它如何打破SFINAE.所以我的问题归结为:

  • 为什么这样的改变会"改善模板参数演绎失败"
  • 你举个例子吗?

小智 21

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

struct S {
  NonCopyable field;
} s;

int main() {
  return sizeof S(s);
}
Run Code Online (Sandbox Code Playgroud)

这里NonCopyable是不可复制的,但是当显式提供复制构造函数时,不会创建隐式复制构造函数.

因为S,用户不提供复制构造函数,因此创建了隐式复制构造函数.此复制构造函数将复制NonCopyable field不可复制的字段,因此复制构造函数将是格式错误的.

In main,采用复制构造S对象的大小.这需要一个复制构造函数S,但实际上并没有调用它.

在C++ 03中,这是有效的.复制构造函数将是格式错误的,但由于没有复制,所以没关系.

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

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