c++ 什么是std::ranges::partial_sort_copy的具体用例?

wfypjpf4  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(145)

我在代码中发现了一个问题,导致std::ranges::partial_sort_copy中的投影不匹配。阅读cppreference之后,我想不出proj1proj2需要不同的合理情况。
这个算法提供两种不同的投影的动机是什么?

oogrdqng

oogrdqng1#

当输入范围的类型和输出范围的类型不匹配时,您需要它。请考虑以下示例:

#include <string>
#include <ranges>
#include <algorithm>
#include <iostream>

int main() {
    std::string names[] = {
        "alpha",
        "beta",
        "tau",
        "pi",
        "omega"
    };
    std::string_view shortest_three[3];

    std::ranges::partial_sort_copy(names, shortest_three,
                                   {},                         // std::ranges::less 
                                   &std::string::length,       // proj1
                                   &std::string_view::length); // proj2
    // note: It might not be allowed to take the address of
    //       member functions in std::string/std::string_view.
    //       (unspecified behavior, see [namespace.std]/6)
    //       To be on the safe side, we would have to wrap access to length()
    //       in a lambda expression.

    for (auto view : shortest_three) {
        std::cout << view << '\n';
    }
}

该输出:

pi
tau
beta

在这个例子中,如果目标范围包含std::string对象,这将是浪费的,因为我们可以将最短的三个字符串存储为const char*std::string_view。因此,这里应用了两种不同的投影。

  • 技术上 * 你总是可以创建一个涵盖两种情况的单一投影:
auto proj = []<typename T>(const T& x) {
    // note: in this specific case, we don't need this if-statement,
    //       because the name of the member function is the exact same for
    //       both types. However, this may not always be the case, e.g.
    //       we need .length() for one type and .size() for another.
    if constexpr (std::is_same_v<T, std::string>) {
        return x.length();
    }
    else {
        return x.length();
    }
};

然而,提供两个单独的投影通常更简洁。

相关问题