我对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 ++”。任何帮助将不胜感激。
答案 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
正如您所看到的,当其中一个类型比另一个类型更大时,编译器将会 转换它为你。
答案 1 :(得分:0)
您可以使用boost::variant
或boost::any
来提高类型安全性和可扩展性。如果类型集是有限的并且在编译时已知,则使用boost::variant
,否则使用boost::any
(例如,如果可插入库可以引入新类型)。
如果是boost::variant
,您将能够为操作编写模板化方法,并且boost会将它们转换为所有可能类型组合的运行时函数指针。
在升级文档中查看更多详细信息。