我的一个项目中有很多自定义数据类型,它们共享一个公共基类.
我的数据(来自数据库)有一个数据类型,它由基类的枚举区分.我的体系结构允许特定的数据类型专门用于派生类,或者它可以由基类处理.
当我构造一个我特定的数据类型时,我通常直接调用构造函数:
Special_Type_X a = Special_Type_X("34.34:fdfh-78");
a.getFoo();
Run Code Online (Sandbox Code Playgroud)
有一些模板魔术也可以像这样构建它:
Type_Helper<Base_Type::special_type_x>::Type a = Base_Type::construct<Base_Type::special_type_x>("34.34:fdfh-78");
a.getFoo();
Run Code Online (Sandbox Code Playgroud)
对于枚举类型的某些值,可能没有专门化
Type_Helper<Base_Type::non_specialized_type_1>::Type == Base_Type
Run Code Online (Sandbox Code Playgroud)
当我从数据库中获取数据时,在编译时不知道数据类型,因此有第三种方法来构造数据类型(来自QVariant):
Base_Type a = Base_Type::construct(Base_type::whatever,"12.23@34io{3,3}");
Run Code Online (Sandbox Code Playgroud)
但是我当然希望调用正确的构造函数,所以该方法的实现过去看起来像:
switch(t) {
case Base_Type::special_type_x:
return Base_Type::construct<Base_Type::special_type_x>(var);
case Base_Type::non_specialized_type_1:
return Base_Type::construct<Base_Type::non_specialized_type_1>(var);
case Base_Type::whatever:
return Base_Type::construct<Base_Type::whatever>(var);
//.....
}
Run Code Online (Sandbox Code Playgroud)
这段代码是重复的,因为基类也可以处理新类型(添加到枚举),我提出了以下解决方案:
// Helper Template Method
template <Base_Type::type_enum bt_itr>
Base_Type construct_switch(const Base_Type::type_enum& bt, const QVariant& v)
{
if(bt_itr==bt)
return Base_Type::construct<bt_itr>(v);
return construct_switch<(Base_Type::type_enum)(bt_itr+1)>(bt,v);
}
// Specialization for the last available (dummy type): num_types
template <>
Base_Type construct_switch<Base_Type::num_types>(const Base_Type::type_enum& bt, const QVariant&)
{ …Run Code Online (Sandbox Code Playgroud) Fortran具有计算效率,称为"计算goto".该构造使用分支表中的索引来执行直接转到.如果我没记错的语法是:
go to index (label1, label2, ...)
Run Code Online (Sandbox Code Playgroud)
其中索引用于引用括号列表中的代码指针(标签).
我有一个案例,计算goto是一个比switch语句更好的解决方案,并希望构建一个,但无法弄清楚如何.
现在在jibes和slings到来之前,编译器可以优化计算的goto,但我不能保证它会.
始终可以使用switch语句.在某些情况下,可以将switch语句优化为跳转表(计算goto的实现).但是,这只有在案例值的范围几乎是密集覆盖时才有可能(在低值到高值的范围内,每个整数几乎都有一个case语句).如果不是这种情况,则实现可能是二叉树.编译器编写器可以选择在适当的时候优化跳转表.在二叉树总是满足switch语句的语义的情况下,有时跳转表就足够了,让我问一下我是否可以在适当的时候保证跳转表.我无法控制编译器编写器.
作为一个简单的例子,我经常写词法分析器(FSM),我使用三个数据结构,一个用于将输入映射到可接受的字母表,一个用于执行节点转换,一个用于根据当前状态和输入执行一些代码值.FSM的实现是Mealy机器,而不是Moore机器,因此动作是在弧(转换)上执行而不是在节点上执行.
执行的操作通常很小,通常不超过一行源代码.我认识到可以使用函数,并且它们的使用消除了对跳转表的需要.但我相信我不能"指向"内联函数,因此,函数是从可调用程序关闭的.在大多数情况下,这比使用跳转表优化的switch语句效率低.如果我可以使用跳转表,那么我就避免了编译器编写者对优化的看法以及能够编写高效代码的问题.
关于与Fortran计算goto相关的问题,下面提到的一般情况.这不是对那些评论的批评.但质量问题,即使它们是真的,也没有回答这个问题.
下面有一个答案void* &&label;,我要感谢你.但是,唉,正如您所指出的那样,这是非标准的C/C++,很可能在将来不存在.所以,最好不要这样做.
我希望我已经回答了"获得更好的编译器"的评论.我希望我至少解决了使用函数指针的问题.最后,这对我来说是一个好奇的时刻.我不认为我应该提供我为什么认为这个问题具有一定的携带能力的杀菌史.但现在我知道了.无论什么时候,我的意思是什么时候,我写信给这个小组,我最好告诉你我所有的鸭子是什么,这样他们就可以被击落.
大家好.