NoS*_*tAl 4 c++ range-v3 c++20
我知道这个问题听起来很奇怪,所以这里有一些上下文。
最近我很失望地得知 C++20 范围内的 map reduce 并不像人们期望的那样工作,即
const double val = data | transform(...) | accumulate (...);
Run Code Online (Sandbox Code Playgroud)
不起作用,您必须以这种不自然的方式编写它:
const double val = accumulate(data | transform(...));
Run Code Online (Sandbox Code Playgroud)
可以在此处和此处找到详细信息,但归结为累积无法消除 2 个不同用例之间的歧义的事实。
所以这让我想到:
如果 C++20 要求你必须使用管道来使用范围,也就是你不能写
vector<int> v;
sort(v);
Run Code Online (Sandbox Code Playgroud)
但你必须写
vector<int> v
v|sort();
Run Code Online (Sandbox Code Playgroud)
那会解决歧义问题吗?
如果是这样,尽管对使用std::sortSTL 算法和其他 STL 算法的人来说很不自然,但我想知道从长远来看这是否是更好的设计选择。
注意:如果这个问题太模糊,可以投票结束,但我觉得这是一个合理的设计问题,可以以相对公正的方式回答,特别是如果我对问题的理解是错误的。
您需要区分范围算法和范围适配器。算法是对一系列值执行通用操作的函数。适配器是创建范围视图的函数,这些视图修改范围的表示。适配器由|操作员链接;算法只是常规函数。
有时,相同的概念事物可以具有算法和适配器形式。transform既作为算法又作为适配器存在。前者将变换存储为输出范围;后者创建输入的视图范围,根据请求懒惰地计算转换。
这些是针对不同需求和用途的不同任务。
另请注意,C++20 中没有sort 适配器。排序适配器必须创建一个视图范围,该范围以某种方式混合在源范围中的元素周围。它必须为新的值序列分配存储空间(即使它只是对值的迭代器/指针/索引进行排序)。并且排序必须在构建时完成,因此不会发生懒惰的操作。
这也是为什么accumulate不能那样工作的原因。这不是“歧义”的问题;这是操作的基本性质的问题。累加从一个范围计算一个值;它不会从现有范围计算新范围。那是算法的工作,而不是适配器的工作。
有些任务在算法形式中很有用。某些任务在适配器形式中很有用(您会发现很少有zip类似算法)。有些任务对两者都有用。但是因为它们是用于不同目的的两个独立概念,所以它们具有不同的调用方式。
这能解决歧义问题吗?
是的。
如果只有一种方式来写某件事,那么这种方式必定是唯一可能的解释。如果算法“调用”只能是对必须|通过左侧范围的操作完成的算法的部分调用,那么您甚至不会有算法调用是部分还是全部的问题。它总是片面的。
从这个意义上来说,没有任何歧义。
但如果你走了那条路,你最终会得到这样的结果:
auto sum = accumulate("hello"s);
Run Code Online (Sandbox Code Playgroud)
它实际上并没有char对该字符串中的 s 求和,实际上是一个占位符,正在等待一个范围与初始值一起累积"hello"s。
| 归档时间: |
|
| 查看次数: |
404 次 |
| 最近记录: |