dav*_*ave 4 c++ c++20 std-ranges
我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)
您在原始范围上使用算法 ( max/ max_element),该算法除了为您提供该范围中的元素/迭代器之外什么也做不了。
如果您只想要投影值,请先进行投影(通过 a 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
Run Code Online (Sandbox Code Playgroud)
这是一个演示。
正如这个答案std::string::size中提到的,不允许使用 的地址,因此您应该使用 lambda。但一般来说,基于成员函数进行投影就可以很好地工作,只要它不是 std 函数。
这里我想要最长字符串的大小,但算法仅返回字符串或迭代器。
事实上,根据[namespace.std#6]:
让
F表示一个标准库函数 ([global.functions])、一个标准库静态成员函数或一个标准库函数模板的实例。除非F指定了 可寻址函数,否则如果 C++ 程序显式或隐式尝试形成指向 的指针,则其行为是未指定的(可能是格式错误的)F。
这是未指定的行为,因为您被禁止提取string::size.
可以使用views::transform将原始范围转换为元素为大小值的范围,然后取最大值。
auto size = std::ranges::max(
vec | std::views::transform([](auto& s) { return s.size(); }));
std::cout << size << '\n';
Run Code Online (Sandbox Code Playgroud)