在 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/