chapel - 可以将类型实例化与值实例化分开吗?

标签 chapel

在 C++ 中,我可以在编译时实例化一个泛型类型,然后在运行时构造它:

struct Vertex {};
struct Edge   {};

template<typename NodeType, typename IdType>
struct Wrapper {
  IdType id;

  Wrapper(IdType id) : id{id} {};
};

int main() {
  using vertexWrapper = Wrapper<Vertex, int>;
  vertexWrapper v(3);
}

变量被清楚地分开,类型永远不会看起来/感觉像值。我正在尝试在教堂做类似的事情:
record Vertex {}
record Edge   {}

record Wrapper {
  type nodeType;
  type idType;   
  var id: idType;

  proc init(id) {
    this.id = id;
  }
}

type vertexWrapper = Wrapper(Vertex, int);

var v1 = 3: vertexWrapper;

当我编译这段代码时,我得到:
chpl -o graph-add-inclusion --cc-warnings test.chpl
test.chpl:9: In initializer:
test.chpl:10: error: can't omit initialization of field "nodeType", no type or default value provided
test.chpl:10: error: can't omit initialization of field "idType", no type or default value provided

有没有办法在 Chapel 中将类型构造与值构造分开,以实现我在示例中尝试获得的标记类型的效果?我使用标记类型来实现两种实体(这里的顶点和边)通用的单一实现,但我希望这些实体是不同的类型。

还有一个相关的问题。我应该可以写:
type vertexWrapper = Wrapper(Vertex);

然后从我的构造函数中单独推导出整数?

似乎在定义时检查构造函数,而不能将类型与值分开提供。我做对了吗,如果我做对了,这是否会在 future 发生变化?

最佳答案

您遇到的问题是您定义的初始化程序,而不是您使用的类型别名。由于您如何定义它,可以想象用户可以尝试编写以下内容:

var x = new Wrapper(1); // type is inferred from the new's return
并且初始化程序不知道如何处理 nodeType 和 idType 字段。因此,您的初始化程序需要在其主体内显式设置它们。
我同意在您使用实例化时让初始化器找出它们的值会很好,并预计这是我们将来会支持的东西。在短期内,你可以通过一点点重复的工作来获得你想要的东西。
为此,首先您可以更新初始化程序,以便它可以根据相应的参数找出 idType。
proc init(id) {
  idType = id.type;
  this.id = id;
}
但是,这对 nodeType 字段没有帮助,因为在您所描述的内容中没有初始化程序可以依赖的相应值字段。这意味着您必须手动将其提供给初始化程序。您可以通过访问其 nodeType 字段从您的类型别名以一般方式执行此操作:
var v1 = new vertexWrapper(vertexWrapper.nodeType, 3);
但是您还需要更新初始化程序以将其作为参数。因此,创建实例 v1 必须如下所示:
record Vertex {}
record Edge   {}

record Wrapper {
  type nodeType;
  type idType;   
  var id: idType;

  proc init(type nodeType, id) {
    this.nodeType = nodeType;
    this.idType = id.type;
    this.id = id;
  }
}

type vertexWrapper = Wrapper(Vertex, int);

var v1 = new vertexWrapper(vertexWrapper.nodeType, 3);
希望这是一个在短期内适用于您的用例的解决方案。

Should I be able to just write:

type vertexWrapper = Wrapper(Vertex);

and then have integer deduced separately from my constructor?


我们目前不支持部分实例化,所以 Wrapper(Vertex)不是你可以写的东西。如果您希望将 idType 设置为像 int 这样的通用值,您可以将其作为默认值提供给 type 字段:
type idType = int;
这将允许您仅通过 Wrapper(Vertex) 指定 nodeType ,但这意味着 idType 被锁定到 int 中,除非您使用 new ( var x = new Wrapper(Vertex, 3.0); ) 创建实例化,或者除非您与 nodeType 同时指定其他内容。

关于chapel - 可以将类型实例化与值实例化分开吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49930764/

相关文章:

derived-class - 在 Chapel 中接受派生类的类方法

list-comprehension - 将数组分配给教堂类中的属性

chapel - 尝试使用 forall 循环对矩阵中的所有元素求和时遇到错误

loops - Chapel 中的稀疏迭代

performance - 将元组有效地处理为固定大小的向量

arrays - 有没有办法从教堂的数组中打印格式化表格?

chapel - 远程变量声明

chapel - 将 C 数组指针包装为 Chapel 数组的最佳方法

sparse-matrix - 我什么时候需要在 Chapel 稀疏矩阵中包含 LayoutCS?