我正在阅读 上的文档std::expected::operator==
,显然它对 SFINAE 不友好。它不是说“如果 [类型不可等价比较],则不参与过载解析”,而是说“程序格式不正确 [在这种情况下]”。
确实如此:
#include <concepts>
#include <expected>
struct A {};
static_assert(!std::equality_comparable<std::expected<A, A>>);
此断言在 MSVC 和带有 libc++ 的 Clang 上失败,并在带有 MSVC STL 的 Clang 上导致硬错误。
但为什么它不适合 SFINAE 呢?
std::expected<T,U>
无论如何都需要T
并且U
是完整的,所以似乎没有什么可以阻止对其的所有操作以实现 SFINAE 友好性。
我认为它只是被忽视了。
直到 2024 年 4 月,
operator==
类似的图书馆类型(如、、std::pair
等)从这个意义上来说也不符合 SFINAE 的要求。std::tuple
std::optional
std::variant
它们通过P2944R3变得对 SFINAE 友好,并且还指出,这种情况可能只是在没有任何意图的情况下发生的。
措辞变化从这里开始在论文中列出。如果某个子句最初说的是“要求: ”,则意味着如果条件不满足,则程序格式不正确(即硬错误)。如果它最初说的是“先决条件: ”,则不满足条件会导致程序出现未定义的行为。当它现在改为“约束: ”时,不满足条件意味着重载不参与重载解析(即它是 SFINAE 友好的)。
我的猜测是那件事
std::expected
同样也被遗忘了。