从 std::ranges 算法中获取预测值
Get projected value from std::ranges algorithms
我正在使用 std::ranges
(max
和 max_element
)的算法进行投影。
结果是否也可能是预测值?目前我必须在 returned 值上再次调用投影函数。
示例:
这里我想要最长字符串的大小,但算法 return 只有字符串或它的迭代器。
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;
}
您在原始范围内使用算法 (max
/max_element
),它只能给您一个 element/iterator 进入范围。
如果您只需要投影值,请进行投影(通过 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。
如中所述,不允许使用std::string::size
的地址,因此您应该改用lambda。不过,一般来说,基于成员函数进行投影就可以了,只要它不是标准函数即可。
Here I want the size of the longest string, but the algorithms return
only the string or an iterator to it.
其实根据[namespace.std#6]:
Let F
denote a standard library function ([global.functions]), a
standard library static member function, or an instantiation of a
standard library function template. Unless F
is designated an
addressable function, the behavior of a C++ program is unspecified
(possibly ill-formed) if it explicitly or implicitly attempts to form
a pointer to F
.
这是未指定的行为,因为您被禁止提取 string::size
的地址。
可以用views::transform
把原来的范围转换成元素为size值的范围,然后取最大值。
auto size = std::ranges::max(
vec | std::views::transform([](auto& s) { return s.size(); }));
std::cout << size << '\n';
我正在使用 std::ranges
(max
和 max_element
)的算法进行投影。
结果是否也可能是预测值?目前我必须在 returned 值上再次调用投影函数。
示例: 这里我想要最长字符串的大小,但算法 return 只有字符串或它的迭代器。
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;
}
您在原始范围内使用算法 (max
/max_element
),它只能给您一个 element/iterator 进入范围。
如果您只需要投影值,请进行投影(通过 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。
如std::string::size
的地址,因此您应该改用lambda。不过,一般来说,基于成员函数进行投影就可以了,只要它不是标准函数即可。
Here I want the size of the longest string, but the algorithms return only the string or an iterator to it.
其实根据[namespace.std#6]:
Let
F
denote a standard library function ([global.functions]), a standard library static member function, or an instantiation of a standard library function template. UnlessF
is designated an addressable function, the behavior of a C++ program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer toF
.
这是未指定的行为,因为您被禁止提取 string::size
的地址。
可以用views::transform
把原来的范围转换成元素为size值的范围,然后取最大值。
auto size = std::ranges::max(
vec | std::views::transform([](auto& s) { return s.size(); }));
std::cout << size << '\n';