从抽象类向下转换到右侧模板的最佳方式
Best way to downcast to right template from abstract class
我最近有一个C++赋值,在那里我遇到了一个关于多态性的问题。
我们需要将值存储在模板化的类中,该类继承自抽象接口类。
enum eOperandType {
Int8,
Int16,
Int32,
Float,
Double
};
class IOperand {
public:
virtual eOperandType getType() const = 0; // Type of the instance
virtual IOperand const *operator+(IOperand const &rhs) const = 0;
virtual ~IOperand() {}
};
template<typename T>
class Operand : public IOperand {
public:
Operand(T const &n, eOperandType type);
eOperandType getType() const;
IOperand const *operator+(IOperand const &rhs) const;
T const value;
eOperandType const type;
};
对于所有的作业,我们被禁止编辑IOperand类,但可以自由使用后面需要的任何类。
在代码执行的后期,数字被实例化,然后作为IOperand*存储在容器中。然后我们得到这个列表来操纵数字。
我的问题是找到如何将IOperand*向下转换为正确的操作数类型,以便对其进行操作并获得其值。
我尝试了一周的多种方法,研究了所有模板的行为(当我尝试使用Operand<op.getType()>
,T是枚举时遇到了麻烦)
我的实际设计使用了很多交换机:
switch (op.value->getType()) {
case Int8:
if (dynamic_cast<Operand<int8_t>*>(op.value.get())->value != dynamic_cast<Operand<int8_t>*>(stack.front().get())->value) {
throw RuntimeError("Assert failed. Whoopsie");
}
break;
case Int16:
if (dynamic_cast<Operand<int16_t>*>(op.value.get())->value != dynamic_cast<Operand<int16_t>*>(stack.front().get())->value) {
throw RuntimeError("Assert failed. Whoopsie");
}
break;
case Int32:
if (dynamic_cast<Operand<int32_t>*>(op.value.get())->value != dynamic_cast<Operand<int32_t>*>(stack.front().get())->value) {
throw RuntimeError("Assert failed. Whoopsie");
}
break;
case Float:
if (dynamic_cast<Operand<float>*>(op.value.get())->value != dynamic_cast<Operand<float>*>(stack.front().get())->value) {
throw RuntimeError("Assert failed. Whoopsie");
}
break;
case Double:
if (dynamic_cast<Operand<double>*>(op.value.get())->value != dynamic_cast<Operand<double>*>(stack.front().get())->value) {
throw RuntimeError("Assert failed. Whoopsie");
}
break;
default:
throw RuntimeError("wut");
break;
}
解决我的问题最好的清洁解决方案是什么?我需要在多个位置和函数上"向下转换"我的值,以便操作该值,这里的断言代码只是其他代码中的一个例子。
我可以在这里使用C++14,但不能使用任何外部库。
当我试着用T的Operand时撞墙了枚举
模板在编译时进行评估。编译器为您使用的每种类型生成代码。像op.getType()
这样的动态值需要编译器在编译之后创建代码,这在JIT编译的语言中当然是可能的,但在C++中则不然。
恐怕你的问题没有"漂亮"的解决办法。正如您所展示的,您确实需要一种switch语句,并根据getType()
的值来决定您的演员阵容。根据您的使用情况,虚拟函数可以帮助您,例如,如果您想知道T
的字节大小
virtual size_t getSizeOf()
{
return sizeof(T);
}
但由于不允许修改IOperand
,因此您只能使用您的解决方案。
相关文章:
- 在c代码之间共享数据的最佳方式
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 在reactor中存储eventHandlers的最佳方式是什么
- 在AVX通道中混洗的最佳方式
- 从 T 创建 std::future 的最佳方式<T>
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- 对列表列表中的元素进行分组的最佳方式
- 利用 GPU 的最佳方式
- 使用 QT C++过滤大数据的最佳方式
- 算法设计:用边界数字表示 2D 网格的最佳方式,以C++?
- 在C++中共享键值对的最佳方式
- 为Catch2中的外部文本文件指定路径的最佳方式
- 代表Quarto棋盘游戏棋子的最佳方式
- 等待线程的最佳方式是什么
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 创建控制台菜单C++的最佳方式
- 只显示片段着色器的最佳方式是什么
- 复制文件的最佳方式是什么,以便我可以在复制过程中轻松取消复制?