【问题标题】:Cartesian product of immutable ranges不可变范围的笛卡尔积
【发布时间】:2014-01-26 20:02:48
【问题描述】:

为什么我们不能计算两个不可变范围的笛卡尔积?

以下代码:

import std.stdio;
import std.algorithm;

void main() {

    immutable int[] B = [ 1, 2, 3 ];
    immutable int[] C = [ 4, 5, 6 ];
    auto BC = cartesianProduct(B, C);

    writeln(BC);
}

投掷:

/usr/include/dmd/phobos/std/range.d(4199): Error: cannot modify struct result._ranges_field_1 Repeat!(immutable(int)) with immutable members
/usr/include/dmd/phobos/std/range.d(4503): Error: template instance std.range.Zip!(immutable(int)[], Repeat!(immutable(int))) error instantiating
/usr/include/dmd/phobos/std/algorithm.d(11674):        instantiated from here: zip!(immutable(int)[], Repeat!(immutable(int)))
laurent_test.d(8):        instantiated from here: cartesianProduct!(immutable(int)[], immutable(int)[])
/usr/include/dmd/phobos/std/algorithm.d(11674): Error: template instance std.range.zip!(immutable(int)[], Repeat!(immutable(int))) error instantiating
laurent_test.d(8):        instantiated from here: cartesianProduct!(immutable(int)[], immutable(int)[])
laurent_test.d(8): Error: template instance std.algorithm.cartesianProduct!(immutable(int)[], immutable(int)[]) error instantiating

此外,如果第二个但第一个不可变被删除,它就可以工作。

根据 phobos 实现,范围之一是 inputRange,另一个是 forwardRange。为什么会有这样的模板约束?

【问题讨论】:

  • 请注意,人们通常想要的是不可变成员的可变数组,例如immutable(int)[]immutable int[] 等价于immutable(int[]),比第一种限制更多。不能说它适用于您的问题,尤其是因为它不能解决问题。

标签: d phobos


【解决方案1】:

我绝对不是 D 方面的专家,但我去年问过 similar question,这个 answer from Jonathan M Davis 非常好。

TL;DR:范围不能是不可变的,因为它不遵守 4 条规则:

R r = void;       // can define a range object
if (r.empty) {}   // can test for empty
r.popFront();     // can invoke popFront()
auto h = r.front; // can get the front of the range

你能猜出罪魁祸首吗? popFront

【讨论】:

  • 确实,静态断言(isForwardRange!(typeof(B))) 失败了。
  • 很抱歉我不接受这个答案,因为我什么都不懂。例如chain () 函数起作用,因为它使用Unqual 模板。计算笛卡尔积不需要 popFront 不是吗?为什么我们需要输入和前向范围?
  • 是的,我不认为这是这里的问题,因为即使明确切片它应该删除顶级不可变,也不起作用。看起来这里的某个地方试图在内部分配给类型,这就是它的绊脚石;我倾向于它是实现中的一个潜在错误,但尚未检查源代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
  • 2014-08-30
相关资源
最近更新 更多