是否有任何 C++ 语言障碍阻止采用 D 范围?
这是一个 C++/D 交叉问题.D 编程语言 有 范围 - 与 C++ 库如 Boost.Range- 不基于迭代器对.官方的 C++ Ranges Study Group 似乎陷入了制定技术规范的困境.
This is a C++ / D cross-over question. The D programming language has ranges that -in contrast to C++ libraries such as Boost.Range- are not based on iterator pairs. The official C++ Ranges Study Group seems to have been bogged down in nailing a technical specification.
问题:当前的 C++11 或即将推出的 C++14 标准是否存在阻碍采用 D 范围的任何障碍 - 以及 <algorithm> 的适当范围限定版本;
-批发?
Question: does the current C++11 or the upcoming C++14 Standard have any obstacles that prevent adopting D ranges -as well as a suitably rangefied version of <algorithm>
- wholesale?
我不太了解 D 或其范围,但它们看起来很懒惰且可组合,并且能够提供 STL 算法的超集.鉴于他们声称 D 取得了成功,将其作为 C++ 库似乎非常好.我想知道 D 的独特功能(例如字符串混合、统一的函数调用语法)对于实现其范围有多么重要,以及 C++ 是否可以在不费力气的情况下模仿它(例如 C++14 constexpr
似乎非常相似到 D 编译时函数评估)
I don't know D or its ranges well enough, but they seem lazy and composable as well as capable of providing a superset of the STL's algorithms. Given their claim to success for D, it would seem very nice to have as a library for C++. I wonder how essential D's unique features (e.g. string mixins, uniform function call syntax) were for implementing its ranges, and whether C++ could mimic that without too much effort (e.g. C++14 constexpr
seems quite similar to D compile-time function evaluation)
注意:我正在寻求技术答案,而不是意见 D 范围是否是作为 C++ 库的正确设计.
Note: I am seeking technical answers, not opinions whether D ranges are the right design to have as a C++ library.
推荐答案
我不认为 C++ 中存在任何固有的技术限制,这使得无法定义 D 风格的系统C++ 中的范围和相应的算法.最大的语言级别问题是 C++ 基于范围的 for
循环要求 begin()
和 end()
可以在范围,但假设我们会使用 D 样式范围来定义库的长度,扩展基于范围的 for
循环来处理它们似乎是一个微小的变化.
I don't think there is any inherent technical limitation in C++ which would make it impossible to define a system of D-style ranges and corresponding algorithms in C++. The biggest language level problem would be that C++ range-based for
-loops require that begin()
and end()
can be used on the ranges but assuming we would go to the length of defining a library using D-style ranges, extending range-based for
-loops to deal with them seems a marginal change.
我在 C++ 中对 D 样式范围的算法进行试验时遇到的主要技术问题是,我无法使算法与基于迭代器(实际上是光标)的实现一样快.当然,这可能只是我的算法实现,但我还没有看到任何人在 C++ 中提供了一套合理的基于 D 风格范围的算法,我可以对其进行分析.性能很重要,C++ 标准库至少应该提供低效率的算法实现(算法的通用实现称为弱效率,如果它在应用于数据结构时至少同样快作为使用相同编程语言使用相同数据结构的相同算法的自定义实现).我无法创建基于 D 风格范围的弱效算法,而我的目标实际上是强效算法(类似于弱效但允许任何编程语言并且只假设相同的底层硬件).
The main technical problem I have encountered when experimenting with algorithms on D-style ranges in C++ was that I couldn't make the algorithms as fast as my iterator (actually, cursor) based implementations. Of course, this could just be my algorithm implementations but I haven't seen anybody providing a reasonable set of D-style range based algorithms in C++ which I could profile against. Performance is important and the C++ standard library shall provide, at least, weakly efficient implementations of algorithms (a generic implementation of an algorithm is called weakly efficient if it is at least as fast when applied to a data structure as a custom implementation of the same algorithm using the same data structure using the same programming language). I wasn't able to create weakly efficient algorithms based on D-style ranges and my objective are actually strongly efficient algorithms (similar to weakly efficient but allowing any programming language and only assuming the same underlying hardware).
在试验基于 D 风格范围的算法时,我发现这些算法比基于迭代器的算法更难实现,并且发现有必要处理杂乱无章的问题以解决它们的一些限制.当然,目前在 C++ 中指定算法的方式也不是所有东西都是完美的.我想如何更改算法及其使用的抽象的粗略概述可能是 STL 2.0页.然而,这个页面并没有真正涉及范围,因为这是一个相关但有些不同的主题.我宁愿设想基于迭代器(好吧,真的是光标)的范围而不是 D 样式范围,但问题不在于那个.
When experimenting with D-style range based algorithms I found the algorithms a lot harder to implement than iterator-based algorithms and found it necessary to deal with kludges to work around some of their limitations. Of course, not everything in the current way algorithms are specified in C++ is perfect either. A rough outline of how I want to change the algorithms and the abstractions they work with is on may STL 2.0 page. This page doesn't really deal much with ranges, however, as this is a related but somewhat different topic. I would rather envision iterator (well, really cursor) based ranges than D-style ranges but the question wasn't about that.
C++ 中所有范围抽象都面临的一个技术问题是必须以合理的方式处理临时对象.例如,考虑这个表达式:
One technical problem all range abstractions in C++ do face is having to deal with temporary objects in a reasonable way. For example, consider this expression:
auto result = ranges::unique(ranges::sort(std::vector<int>{ read_integers() }));
根据 ranges::sort()
或 ranges::unique()
是否惰性,需要处理临时范围的表示.仅仅提供源范围的视图对于这两种算法都不是一种选择,因为临时对象将在表达式结束时消失.一种可能性是移动范围,如果它以 r 值的形式出现,则 ranges::sort()
和 ranges::unique()
需要不同的结果区分实际参数是临时对象还是独立保持活动的对象的情况.D 没有这个特殊问题,因为它是垃圾收集的,因此在任何一种情况下,源范围都会保持活动状态.
In dependent of whether ranges::sort()
or ranges::unique()
are lazy or not, the representation of the temporary range needs to be dealt with. Merely providing a view of the source range isn't an option for either of these algorithms because the temporary object will go away at the end of the expression. One possibility could be to move the range if it comes in as r-value, requiring different result for both ranges::sort()
and ranges::unique()
to distinguish the cases of the actual argument being either a temporary object or an object kept alive independently. D doesn't have this particular problem because it is garbage collected and the source range would, thus, be kept alive in either case.
上面的例子还显示了可能是惰性求值算法的问题之一:因为任何类型,包括不能以其他方式拼出的类型,都可以通过 auto
变量或模板函数推导出来,在表达式的末尾没有强制进行惰性求值.因此,可以从表达式模板中获得结果,而算法并没有真正执行.也就是说,如果将左值传递给算法,则需要确保表达式实际被评估以获得实际效果.例如,任何对整个序列进行变异的 sort()
算法都清楚地在原地进行变异(如果你想要一个版本不在原地执行它,只需复制容器并就地应用版本;如果你只有一个非就地版本,你就无法避免额外的序列,这可能是一个直接的问题,例如,对于巨大的序列).假设它在某种程度上是惰性的,对原始序列的左值访问提供了当前状态的峰值,这几乎可以肯定是一件坏事.这可能意味着对变异算法的惰性评估无论如何都不是一个好主意.
The above example also shows one of the problems with possibly lazy evaluated algorithm: since any type, including types which can't be spelled out otherwise, can be deduced by auto
variables or templated functions, there is nothing forcing the lazy evaluation at the end of an expression. Thus, the results from the expression templates can be obtained and the algorithm isn't really executed. That is, if an l-value is passed to an algorithm, it needs to be made sure that the expression is actually evaluated to obtain the actual effect. For example, any sort()
algorithm mutating the entire sequence clearly does the mutation in-place (if you want a version doesn't do it in-place just copy the container and apply the in-place version; if you only have a non-in-place version you can't avoid the extra sequence which may be an immediate problem, e.g., for gigantic sequences). Assuming it is lazy in some way the l-value access to the original sequence provides a peak into the current status which is almost certainly a bad thing. This may imply that lazy evaluation of mutating algorithms isn't such a great idea anyway.
无论如何,C++ 的某些方面使得无法立即采用 D 样式范围,尽管同样的考虑也适用于其他范围抽象.因此,我认为这些考虑因素也有点超出了这个问题的范围.此外,第一个问题(添加垃圾收集)的明显解决方案"不太可能发生.我不知道 D 中的第二个问题是否有解决方案.可能会出现第二个问题的解决方案(暂称为 operator auto),但我不知道具体的建议或这样的功能实际上会是什么样子.
In any case, there are some aspects of C++ which make it impossible to immediately adopt the D-sytle ranges although the same considerations also apply to other range abstractions. I'd think these considerations are, thus, somewhat out of scope for the question, too. Also, the obvious "solution" to the first of the problems (add garbage collection) is unlikely to happen. I don't know if there is a solution to the second problem in D. There may emerge a solution to the second problem (tentatively dubbed operator auto) but I'm not aware of a concrete proposal or how such a feature would actually look like.
顺便说一句,Ranges Study Group 并没有真正被任何技术细节所困扰.到目前为止,我们只是试图找出我们真正想要解决的问题,并在某种程度上确定解决方案的空间.此外,小组通常根本不会完成任何工作!实际工作总是由个人完成,通常由极少数个人完成.由于工作的主要部分实际上是设计一组抽象,我希望 Ranges Study Group 的任何结果的基础都是由 1 到 3 个人完成的,他们对需要什么以及它应该是什么样子有一定的了解.
BTW, the Ranges Study Group isn't really bogged down by any technical details. So far, we merely tried to find out what problems we are actually trying to solve and to scope out, to some extend, the solution space. Also, groups generally don't get any work done, at all! The actual work is always done by individuals, often by very few individuals. Since a major part of the work is actually designing a set of abstractions I would expect that the foundations of any results of the Ranges Study Group is done by 1 to 3 individuals who have some vision of what is needed and how it should look like.
相关文章