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

Why C++20 allows defaulted comparison to compile even when it is deleted?

提问人:NoSenseEtAl 提问时间:2/5/2021 最后编辑:ShadowRangerNoSenseEtAl 更新时间:2/5/2021 访问量:1162

问:

请考虑以下代码:

struct A {
};
struct B {
    A a;
    bool operator == (const B& other) const = default;
};

Clang 给出了一个很好的警告:

警告:显式默认的相等比较运算符是 隐式删除 [-Wdefaulted-function-deleted] bool 运算符 == (const B& other) const = default;

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

但这是 C++ 有一百万个极端情况,所以可能有一个很好的理由。 也许不是特殊情况的模板?

但是 clang 足够聪明,不会警告这段代码......

struct A {
};

template<typename T>
struct TS{
    T t;
    bool operator == (const TS& other) const = default;
};
int main() {
    TS<int> ti;
}

...所以从理论上讲,标准也可以做同样的事情。

C++ 相等 C++20 defaulted-functions default-comparisons

评论

4赞 HolyBlackCat 2/5/2021
也许是为了与显式默认的构造函数和赋值运算符保持一致?
2赞 StoryTeller - Unslander Monica 2/5/2021
通用代码,我估计。类模板可能会默认它。如果从不使用运算符,则其专用化在实例化时不应格式错误(如类模板的所有格式错误的成员函数体)。
0赞 NoSenseEtAl 2/5/2021
@StoryTeller-UnslanderMonica 也许我误解了你,但 clang 没有在模板情况下发出警告,我认为该功能不是错误,因为仅根据已知用途诊断模板是愚蠢的。
0赞 StoryTeller - Unslander Monica 2/5/2021
不,是我只是错过了“不”这个词。
1赞 ShadowRanger 2/5/2021
@NoSenseEtAl:你说得对。defaulted-functions 标签肯定适用,我也制作了一个 default-comparisons 标签(匹配其他常见默认情况的现有 default-constructor,以及特定于宇宙飞船操作员的更广泛的问题)。宇宙飞船操作员是相关的,但在与其他问题联系起来方面并不是超级有帮助(大多数被它标记的人实际上是在专门询问),所以我删除了它。operator<=>

答:

4赞 Yakk - Adam Nevraumont 2/5/2021 #1

在模板中,您可能希望它是否可以存在,否则不可以。==

复制/移动/分配特殊成员功能也使用相同的技术; 也可以删除成员函数。=default;

评论

0赞 ShadowRanger 2/5/2021
不过,我明白为什么 OP 很困惑。您提到的情况可以隐式删除,原因有两个:1) 定义了配对函数(例如,复制构造函数定义删除了隐式移动),或者 2) 成员阻止了函数的生成(例如 成员禁止隐式复制构造函数)。 从未定义过 #2 的函数,但 #2 不会经常出现在其他用例中(用户通常知道他们具有复制/可移动属性)。OP 正在尝试根据(工作)案例 #2 的经验将其用于案例 #1。std::unique_ptr= default= default= default