C++ 为什么是C++;20允许编译默认比较,即使它已被删除?

C++ 为什么是C++;20允许编译默认比较,即使它已被删除?,c++,equality,c++20,defaulted-functions,default-comparisons,C++,Equality,C++20,Defaulted Functions,Default Comparisons,考虑以下代码: struct A { }; struct B { A a; bool operator == (const B& other) const = default; }; 叮当声给出了一个很好的警告: 警告:显式默认的相等比较运算符为 隐式删除[-Wdefaulted函数已删除] 布尔运算符==(常量B和其他)常量=默认值 但我想知道为什么这个准则甚至被标准所接受。 我假设,如果有人在其非模板结构/类中默认了操作符==,那么他的意图是永远不会被删除操作符==

考虑以下代码:

struct A {
};
struct B {
    A a;
    bool operator == (const B& other) const = default;
};
叮当声给出了一个很好的警告:

警告:显式默认的相等比较运算符为 隐式删除[-Wdefaulted函数已删除] 布尔运算符==(常量B和其他)常量=默认值

但我想知道为什么这个准则甚至被标准所接受。 我假设,如果有人在其非模板结构/类中默认了
操作符==
,那么他的意图是永远不会被删除
操作符==

<>这是C++,有一百万个角的情况,所以可能有一个很好的理由。 也许不需要特殊情况模板

但是叮当声足够聪明,可以警告此代码

struct A {
};

template<typename T>
struct TS{
    T t;
    bool operator == (const TS& other) const = default;
};
int main() {
    TS<int> ti;
}
结构A{ }; 模板 结构TS{ T; 布尔运算符==(常量TS和其他)常量=默认值; }; int main(){ TS-ti; }
。。。因此,理论上标准也可以这样做。

在模板中,您可能需要
=
,如果它可以存在,否则就不存在


复制/移动/分配特殊成员功能也使用相同的技术<代码>=默认值也可以删除成员函数。

可能是为了与显式默认构造函数和赋值运算符保持一致,我认为是通用代码。类模板可以默认为它。如果从未使用该运算符(就像类模板的所有格式错误的成员函数体一样),则其专门化在实例化时不应该是格式错误的。@StoryTeller UnslanderMonica也许我误解了你,但clang没有在模板情况下发出警告,我认为一个特性并不是一个bug,因为仅仅在已知的应用程序中诊断模板是愚蠢的。不,是我错过了“不”这个词。@ NoSeNeTeL:你是对的。DefaultedFunctions标签绝对适用,我也做了一个默认比较标签(与其他常见的默认情况下的现有默认构造函数相匹配,并针对spaceship操作符提出了更广泛的问题)。太空船操作员是相关的,但在与其他问题的联系方面没有太大的帮助(大多数被标记的人实际上是问关于操作员的问题),所以我删除了它。我可以理解为什么OP会被混淆。您提到的情况可以隐式删除,原因有两个:1)定义成对函数(例如,复制构造函数定义删除隐式移动),或2)成员阻止生成函数(例如,
std::unique_ptr
成员抑制隐式复制构造函数)
=default
从未定义#2的函数,但#2在其他
=default
用例中并不常见(用户通常知道它们具有复制/可移动属性)。根据(工作)案例1的经验,OP正在尝试对案例2使用
=default