为什么 std::ranges::find 不能编译,而 std::find 工作正常?

Sup*_*pAl 15 c++ c++20 std-ranges

考虑这段代码:

#include <vector>
#include <iostream>
#include <cstdint>
#include <ranges>

int main()
{
    struct S {
        int  a;
        int  b;
        bool operator==(int other) const { return a == other; }
    };
    std::vector<S> iv{
        {1, 2},
        {3, 4}
    };

    // this works
    if (auto const it{std::find(iv.begin(), iv.end(), 1)}; it != iv.end()) {
        std::cout << "Found!\n" << "\n";
    }

    //std::ranges::find(iv, 2); // <-- why does this not compile
    
}
Run Code Online (Sandbox Code Playgroud)

我的印象是范围的调用约定将是相应原始算法的一对一映射(即,只需跳过 and .begin().end()它应该像以前一样工作)。

显然这里的情况并非如此。我缺少什么?

代码链接: https: //godbolt.org/z/3a6z9c5of

康桓瑋*_*康桓瑋 18

ranges::find默认情况下使用将ranges::equal_to范围的元素与值进行比较,并且调用运算符ranges::equal_to约束这两种类型以满足,在您的示例中equality_comparable_withS和。int

equal_comparable_with需要S与自身进行比较,并且需要与 具有共同的参考const int&,这不是你的情况。

简单的解决方法是使用投影功能投影SS::a

if (auto const it{std::ranges::find(iv, 1, &S::a)}; it != iv.end()) {
    std::cout << "Found!\n" << "\n";
}
Run Code Online (Sandbox Code Playgroud)

  • @Evg 那么,说“S”(其中有两个“int”的类型)“等于”“int”是什么意思?当我们考虑相等性时,我们会考虑某些属性……所以“S{1, 2} == 1”和“S{1, 3} == 1”是否意味着“S{1, 2} == 1” 2} == S{1, 3}`? 但“S”甚至无法与其自身相比较,那么我们还能对此说些什么呢?这个例子给我的印象更像是使用“==”来实现“find”的语法便利性,而不是其他任何东西。 (9认同)