在ISO 国际标准 for C ++ 11中,给出了c ++ 2003和C ++ 2011之间差异的摘要。其中一个不同之处是:
[diff.cpp03.special]
更改:隐式声明的特殊成员函数在隐式定义时被定义为已删除 本来就是不合格的。
基本原理:改进模板参数扣除失败。
对原始功能的影响:在不需要定义的上下文中使用这些特殊成员函数之一的有效C ++ 2003程序(例如,在无法评估的表达式中)不良形成。
我没有看到这种特殊功能在哪种情况下会形成错误,以及它如何打破SFINAE。所以我的问题归结为:
答案 0 :(得分:21)
struct NonCopyable {
NonCopyable() {}
private:
NonCopyable(const NonCopyable &);
};
struct S {
NonCopyable field;
} s;
int main() {
return sizeof S(s);
}
这里,NonCopyable
是不可复制的,但是当显式提供复制构造函数时,不会创建隐式复制构造函数。
对于S
,用户不提供复制构造函数,因此创建了隐式复制构造函数。此复制构造函数将复制NonCopyable
field
字段,该字段是不可复制的,因此复制构造函数将格式不正确。
在main
中,采用复制构造的S
对象的大小。这需要S
的复制构造函数,但实际上并没有调用它。
在C ++ 03中,这是有效的。复制构造函数不正确,但由于没有复制,所以没关系。
在C ++ 11中,这是无效的。复制构造函数被标记为已删除,因此即使作为sizeof
的操作数也不能使用。
这允许元编程检测类型是否可复制,这在C ++ 03中是不可能的。
答案 1 :(得分:1)
如果你想要一个具体的例子,std :: pair通常很容易复制,但如果其中一个成员是std :: unique_ptr,则unique_ptr不允许从Lvalue复制,所以它将是格式错误:因此std :: pair默认左值复制操作会自动删除。