为什么不能在函数中使用范围?
Why can't ranges be used if in a function?
我正在尝试获得 range
如下所示 python:
#include <iostream>
#include <ranges>
auto Range(double start, double end, double step)
{
if (start <= end) {
auto step_fun = [=](auto x) { return x * step + start; };
auto end_pred = [=](auto x) { return x <= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
else {
auto step_fun = [=](auto x) { return -x * step + start; };
auto end_pred = [=](auto x) { return x >= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
}
int main() {
auto range = Range(108, 100, 1);
for (auto i : range)
std::cout << i << ' ';
return 0;
}
但是 Visual Studio 告诉我:
Error C3487 'std::ranges::take_while_view<std::ranges::transform_view<std::ranges::iota_view<_Ty,std::unreachable_sentinel_t>,Range::<lambda_3>>,Range::<lambda_4>>': all return expressions must deduce to the same type: previously it was 'std::ranges::take_while_view<std::ranges::transform_view<std::ranges::iota_view<_Ty,std::unreachable_sentinel_t>,Range::<lambda_1>>,Range::<lambda_2>>'
和
Message No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called test
但只有start>end
或start<end
,它可以工作,如:
auto Range(double start, double end, double step)
{
auto step_fun = [=](auto x) { return x * step + start; };
auto end_pred = [=](auto x) { return x <= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
我该如何解决?
一个函数必须有一个 return 类型,auto 不会改变这一点。你的两个 return 有不同的、不兼容的类型,因为每个 lambda 表达式都有一个唯一的类型。
错误消息宁愿掩埋它:blah blah Range::<lambda_3>,Range::<lambda_4>
vs blah blah Range::<lambda_1>,Range::<lambda_2>
你可以做一些算术将它减少到一个 return
auto Range(double start, double end, double step)
{
if (start > end) {
step *= -1;
}
int count = (end - start) / step;
auto step_fun = [=](auto x) { return x * step + start; };
return std::views::iota(0, count)
| std::views::transform(step_fun);
}
警告:如果 step
为负数,此函数仍然存在问题,如果 end
无法从 start
.
访问,您可能想要抛出
因为take_while
和transform
的结果类型包含函数类型作为签名的一部分,但一个函数只能有一个return类型。
除了已经回答的,你还可以删除类型。
#include <iostream>
#include <ranges>
#include <functional>
auto Range(double start, double end, double step)
{
std::function<double(double)> step_fun;
std::function<double(double)> end_pred;
if (start <= end) {
step_fun = [=](auto x) { return x * step + start; };
end_pred = [=](auto x) { return x <= end; };
}
else {
step_fun = [=](auto x) { return -x * step + start; };
end_pred = [=](auto x) { return x >= end; };
}
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
int main() {
auto range = Range(108, 100, 1);
for (auto i : range)
std::cout << i << ' ';
return 0;
}
我正在尝试获得 range
如下所示 python:
#include <iostream>
#include <ranges>
auto Range(double start, double end, double step)
{
if (start <= end) {
auto step_fun = [=](auto x) { return x * step + start; };
auto end_pred = [=](auto x) { return x <= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
else {
auto step_fun = [=](auto x) { return -x * step + start; };
auto end_pred = [=](auto x) { return x >= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
}
int main() {
auto range = Range(108, 100, 1);
for (auto i : range)
std::cout << i << ' ';
return 0;
}
但是 Visual Studio 告诉我:
Error C3487 'std::ranges::take_while_view<std::ranges::transform_view<std::ranges::iota_view<_Ty,std::unreachable_sentinel_t>,Range::<lambda_3>>,Range::<lambda_4>>': all return expressions must deduce to the same type: previously it was 'std::ranges::take_while_view<std::ranges::transform_view<std::ranges::iota_view<_Ty,std::unreachable_sentinel_t>,Range::<lambda_1>>,Range::<lambda_2>>'
和
Message No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called test
但只有start>end
或start<end
,它可以工作,如:
auto Range(double start, double end, double step)
{
auto step_fun = [=](auto x) { return x * step + start; };
auto end_pred = [=](auto x) { return x <= end; };
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
我该如何解决?
一个函数必须有一个 return 类型,auto 不会改变这一点。你的两个 return 有不同的、不兼容的类型,因为每个 lambda 表达式都有一个唯一的类型。
错误消息宁愿掩埋它:blah blah Range::<lambda_3>,Range::<lambda_4>
vs blah blah Range::<lambda_1>,Range::<lambda_2>
你可以做一些算术将它减少到一个 return
auto Range(double start, double end, double step)
{
if (start > end) {
step *= -1;
}
int count = (end - start) / step;
auto step_fun = [=](auto x) { return x * step + start; };
return std::views::iota(0, count)
| std::views::transform(step_fun);
}
警告:如果 step
为负数,此函数仍然存在问题,如果 end
无法从 start
.
因为take_while
和transform
的结果类型包含函数类型作为签名的一部分,但一个函数只能有一个return类型。
除了已经回答的,你还可以删除类型。
#include <iostream>
#include <ranges>
#include <functional>
auto Range(double start, double end, double step)
{
std::function<double(double)> step_fun;
std::function<double(double)> end_pred;
if (start <= end) {
step_fun = [=](auto x) { return x * step + start; };
end_pred = [=](auto x) { return x <= end; };
}
else {
step_fun = [=](auto x) { return -x * step + start; };
end_pred = [=](auto x) { return x >= end; };
}
auto range =
std::views::iota(0)
| std::views::transform(step_fun)
| std::views::take_while(end_pred);
return range;
}
int main() {
auto range = Range(108, 100, 1);
for (auto i : range)
std::cout << i << ' ';
return 0;
}