C++ 可变模板是否足以指定构造类型
我的目标是定义一个模板来创建构造类型,例如:C++ 可变模板是否足以指定构造类型,c++,constructor,variadic-templates,C++,Constructor,Variadic Templates,我的目标是定义一个模板来创建构造类型,例如: MyCT := foo | bar of int | baz of WeirdClass | bat of (String, MyCT) 在内部,前缀将是枚举类型的字节值,因此: {0}或{1,-20}或{2,{weirdo:WeirdClass}或{3,{“像我说的那样”,0}}或{3,对{a',{1626}}}或类似的 看起来变量模板的…语法可能会有所帮助,但我担心以下几点: 是否可以根据枚举值的数量创建多个构造函数 如果枚举值的数量不等于相应
MyCT := foo | bar of int | baz of WeirdClass | bat of (String, MyCT)
在内部,前缀将是枚举类型的字节值,因此:
{0}
或{1,-20}
或{2,{weirdo:WeirdClass}
或{3,{“像我说的那样”,0}}
或{3,对{a',{1626}}}
或类似的
看起来变量模板的…
语法可能会有所帮助,但我担心以下几点:
MyCT
格式的模板,其中ET
是枚举类型。如何确保只使用与枚举值对应的构造函数MyCT
中,et
不在模板的枚举类型et
中,我们是否可以抛出编译时错误MyCT
的类型匹配MyCT
为了让这一点更有趣,让我们也在这种构造类型上定义一个(递归)函数
fuz
,使用类似ML的语法:
let rec fuz = fun (foo) -> 4
| (bar b) -> 2 * b
| (baz w) -> w.eird
| (bat(s,m)) -> length(s) - fuz(m);;
在哪里(说)
<>这里我们进入C++():
不需要奇怪的变量模板。问题不清楚。我看不出编译时的运行时障碍在哪里:为什么要使用枚举标记?这些枚举值是在运行时指定的吗?如果一切都是在编译时提供的,我认为我们可以很容易地重新设计它,并使用一些模板元编程使其工作。这个目标是值得称赞的,但不是真正可以实现的。我真诚的建议是忘掉它。如果你想要ML或Haskell,你知道在哪里可以找到它们。谢谢你的想法,Manu343726。以下内容不应编译,并应给出编译时错误:ConstrType,因为ET有四个值,并且只提供了三种类型。这应该通过检查语法来轻松处理。假设我们有一个具有正确语法的构造类型模板,并将其实例化为如下内容:模板公共类MyCT;模板公共类MyCT:ConstrType{…}(语法除外)我们希望在MyCT中对et进行严格的键入。不是MyCT。是的,我希望完全实例化的模板具有那种ML功能,并且对术语代数做了类似的事情。然而,在这个问题上,我将这一步进一步考虑,现在是否可以简洁地表示C++中一个代数的朴素实现。显然,到目前为止还不是这样。@CarlKlapper作为一个运行时解决方案,多态类型可以是构造类型的直接翻译,如我的示例所示。我认为你在问题中提出的混合方式几乎是不可能的。然而,纯编译时间可能是一种选择,因为C++模板非常强大。如果您感兴趣的话,去年我实现了一个小型编译时Scheme/CAML解释器,不幸的是它没有类型化,但甚至支持Scheme的
集这样的命令性方面代码>。当编译器运行10分钟时,我停止了运行,占用了24GB内存,至少产生了正确的结果:-)
#type WeirdClass = {eird:int};;
struct WeirdClass { int eird; };
struct MyCT { virtual int fuz() const = 0; };
struct foo : MyCT
{
virtual int fuz() const override { return 4; };
};
struct bar : MyCT
{
int b;
bar(int b) : b(b) { }
virtual int fuz() const override { return 2 * b; };
};
struct baz : MyCT
{
WeirdClass w;
baz(const WeirdClass& w) : w(w) { }
virtual int fuz() const override { return w.eird; };
};
struct bat : MyCT
{
std::string s;
const MyCT& m;
bat(const std::string& s, const MyCT& m) : s(s), m(m) { }
virtual int fuz() const override { return s.length() - m.fuz(); };
};
int main()
{
foo f;
bar r{-20}, c{626};
baz z{{8}};
bat a{"Like I said",f};
bat t{"no templates needed",c};
cout << f.fuz() << " " << r.fuz() << " "
<< c.fuz() << " " << z.fuz() << " "
<< a.fuz() << " " << t.fuz() << endl;
}
4 -40 1252 8 7 -1251