【问题标题】:Why does std::equality_comparable not work for std::vector为什么 std::equality_comparable 不适用于 std::vector
【发布时间】:2021-03-12 11:05:55
【问题描述】:

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 内部失败,而不是在受概念保护的函数边界处失败。

这是错误还是预期行为?

【问题讨论】:

  • 因为X 不是equal_comparable
  • 对不起,如果我不清楚。我知道 X 不是平等可比的。然而,这也意味着 std::vector 不是相等可比的。我希望它在那里失败,而不是在向量的实现中。
  • 向量比较运算符对 SFINAE 不友好,即它们是无条件定义的,即使您无法比较它们,也使 vector&lt;X&gt; 满足 equality_comparable 概念。
  • 要使其失败,向量的运算符必须声明为 SFINAE 友好。目前不需要。
  • 我还没见过。但我现在有一段时间没有密切关注了。将标准库的操作符模板概念化肯定会很有意义。

标签: c++ stdvector c++20 c++-concepts


【解决方案1】:

概念只检查声明是否格式正确,不检查定义。

std::vectorcomparison operators 不是 SFINAE 友好的,即它们是无条件声明的,这意味着 operator==(vector&lt;T&gt;, vector&lt;T&gt;) 始终存在,即使 operator==(T, T) 不存在。这就是为什么 equality_comparable&lt;std::vector&lt;T&gt;&gt; 总是很满意,而函数内部的 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 是否应该/将修复它?跨度>
  • @bradgon 标准。请注意,我编写了一个自定义特征来处理这种常见情况,方法是测试 tyoe T 而不是 T 的向量,然后回退到正常特征。
猜你喜欢
  • 2014-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
  • 2017-07-22
  • 2020-02-01
  • 1970-01-01
相关资源
最近更新 更多