C ++基于运行时类型

时间:2016-02-18 12:51:33

标签: c++ casting

我对c ++很陌生,最近我决定为练习编写一个小计算器。我希望计算器能够对整数和浮点数(以及后来不同的数据类型,例如复数)进行操作,但是在尝试决定如何投射时我遇到了一个问题。假设用户想要对整数和浮点数执行操作。我希望在这种情况下将整数转换为float(这是一个相对简单的示例,一旦我实现了更多类型,这将变得更加复杂)。 我已经尝试使用模板进行功能签名,但这对我没有帮助:

template <class T> T add(T a, T b);
//...

//Operation is an enum
//data is a structure comprised of a union and an enum to decide which union member is used
void execute_operation(Operation op, data operand0, data operand1) {
    switch (op) {
        case Addition:
            //is operand0 or operand1 float? cast both to float : keep them as integers
            //also, decide on the cast made which union member of result to use
            data result = add(operand0.value, operand1.value);
        break;
    }
}

我到目前为止唯一的解决方案是硬编码一种铸造表,但我很确定必须有更好的解决方案。我曾经使用ruby和其他一些语言,这些语言对类型有更动态的方法,所以我可能不是“思考c ++”。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您可以使用两个不同的模板参数,让编译器为您执行隐式转换,而不是转换。拿这个小例子

template<typename T, typename U>
auto Add(T lhs, U rhs) -> decltype(lhs + rhs)
{
    return lhs + rhs;
}

int main()
{
   std::cout << typeid(Add(1, .5f)).name() << std::endl;
   std::cout << typeid(Add(1, .5)).name() << std::endl;
   std::cout << typeid(Add(1, 3)).name() << std::endl;
   std::cout << typeid(Add(1.0f, .5f)).name() << std::endl;
   std::cout << typeid(Add(1.0, .5f)).name() << std::endl;
}

输出

f
d
i
f
d

Live Example

正如您所看到的,当其中一个类型比另一个类型更大时,编译器将会 转换它为你。

答案 1 :(得分:0)

您可以使用boost::variantboost::any来提高类型安全性和可扩展性。如果类型集是有限的并且在编译时已知,则使用boost::variant,否则使用boost::any(例如,如果可插入库可以引入新类型)。

如果是boost::variant,您将能够为操作编写模板化方法,并且boost会将它们转换为所有可能类型组合的运行时函数指针。

在升级文档中查看更多详细信息。

相关问题