为什么 std::equality_comparable 不适用于 std::vector?

4

https://godbolt.org/z/P97MaK

我正在探索一些概念,期望`std::is_equality_comparable`适用于向量,但实际上并不适用。
#include <type_traits>
#include <vector>
#include <concepts>


struct X {};

template<std::equality_comparable T>
bool foo( T v){
    return v == v;
}

int main()
{
    foo(10);
    foo(std::vector<X>{});
    
}

编译错误发生在foo内部,而不是由概念保护的函数边界处。

enter image description here

这是一个 bug 还是预期行为?

2
因为 X 不具备相等比较性。 - bolov
向量比较运算符不友好SFINAE,即它们是无条件定义的,使得vector<X>满足equality_comparable概念,尽管你不能比较它们。 - bolov
一般问题是,对于模板类型,std::is_equality_comparable 的预期行为是什么。它是否旨在在可能进行相等比较的情况下返回 true。 - bradgonesurfing
4
若要使其失败,向量的操作符必须声明为 SFINAE 友好。目前这并非必需。 - StoryTeller - Unslander Monica
1
我还没有看到过。但是我已经有一段时间没有密切关注了。将标准库的运算符模板概念化肯定是很有意义的。 - StoryTeller - Unslander Monica
显示剩余2条评论
1个回答

5

这里的概念只检查声明是否格式良好,而不检查定义。

std::vector比较运算符并不符合SFINAE,即它们是无条件声明的,这意味着operator==(vector<T>, vector<T>)始终存在,即使operator==(T, T)不存在也一样。这就是为什么equality_comparable<std::vector<T>>总是被满足,并且在函数内部使用v == v时会出现错误的原因。

为了使其正常工作,向量比较运算符应该受到约束,即:

template< class T, class Alloc >
    requires std::equality_comparable<T>
constexpr ret_type operator==( const std::vector<T,Alloc>& lhs,
                                       const std::vector<T,Alloc>& rhs );

为了修复这个问题,std::library是需要更改标准规范,还是各个供应商gcc/clang/msvc应该/会修复它不确定? - bradgonesurfing
1
@bradgon 这是标准。请注意,我编写了一个自定义的特质,通过测试类型T而不是T的向量来处理这种常见情况,并回退到正常的特质。 - Yakk - Adam Nevraumont

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接