代码之家  ›  专栏  ›  技术社区  ›  perivesta

从std::ranges算法获取投影值

  •  1
  • perivesta  · 技术社区  · 3 年前

    我使用的算法来自 std::ranges max max_element )有一个投影。

    实例 :

    int main()
    {
        const std::vector<std::string> vec = {
            "foo",
            "hello",
            "this is a long string",
            "bar"
        };
    
        //r1 is a string. r2 is an iterator
        const auto r1 = std::ranges::max(vec, {}, &std::string::size);
        const auto r2 = std::ranges::max_element(vec, {}, &std::string::size);
        
        //I have to call size() again
        std::cout << r1 << '\n' << *r2 << '\n';
        std::cout << r1.size() << '\n' << r2->size() << std::endl;
    }
    

    Compiler Explorer

    2 回复  |  直到 3 年前
        1
  •  2
  •   cigien Jorge Eldis    3 年前

    你在使用一种算法( max / max_element

    如果只需要投影值,请进行投影(通过 views::transform )先求长度,然后求最大值

    auto const lens = std::views::transform(vec, &std::string::size);
    
    const auto r1 = std::ranges::max(lens);
    const auto r2 = std::ranges::max_element(lens);
    
    std::cout << r1 << '\n' << *r2 << '\n';  // prints 21 21
    

    demo .


    如中所述 this answer std::string::size 是不允许的,因此您应该使用lambda。不过,一般来说,基于成员函数进行投影效果很好,只要它不是std函数。

        2
  •  2
  •   康桓瑋    3 年前

    这里我想要最长字符串的大小,但是算法返回 仅将字符串或迭代器添加到它。

    [namespace.std#6] :

    允许 F 表示一个标准库函数([global.functions]),一个 F 被指定为 作用 C++程序的行为未指定。 (可能格式错误)如果它显式或隐式地试图形成 指向

    这是未指定的行为,因为您被禁止提取 string::size

    你可以用 views::transform

    auto size = std::ranges::max(
                  vec | std::views::transform([](auto& s) { return s.size(); }));
    std::cout << size << '\n';
    
    推荐文章