提问人:nowox 提问时间:5/5/2023 最后编辑:463035818_is_not_an_ainowox 更新时间:5/6/2023 访问量:129
在 C++ 中重载浮点型的有效方法?
Efficient way to overload float type in C++?
问:
我想存储重量、时间、长度等数量。我想这种方式更具可读性,并避免了此类功能的不匹配:
Velocity computeSpeed(Distance d, Time t);
目前我只有
using float_type = double;
using Velocity = float_type;
using Distance = float_type;
using Time = float_type;
但是,对于我的应用程序,我需要一些转换,例如:
Distance toInches(Distance);
Distance toMillimeters(Distance);
我宁愿拥有这样的东西:
Distance d;
std::cout << d.toInches();
但是,重载基类型可能有一些缺点:
- 它需要重载所有运算符或在浮点类型上使用 CRTP
- 这可能会影响效率
是否可以将“转换”const 方法添加到数值类型中? 附带问题:这种方法是坏的还是矫枉过正的?
注意:我被 C++03 :(困住了
答:
我已经完成了您在 C# 中尝试执行的操作,它的重载功能比 C++ 少得多。结果很棒,因为它可以保护您免受各种错误的影响,并使代码简洁明了。(它消除了偶然的复杂性。
它还允许 IDE 的完成建议功能大放异彩,因为它将向您展示可以对每个变量执行的操作,而不必牢记哪些全局范围函数适用于每个变量。
这样做的方法是为每种不同类型的数量声明一个新类,该类包含某个标准单位的单个值。(当然,您会为您的标准单位选择 SI 系统,对吧?
拥有这些类后,可以重载所有适用的运算符,以便它们在每个类的实例之间以及每个有意义的组合之间工作。
如果你喜欢危险地生活,你甚至可以利用 C++ 的惊人能力来重载类型转换运算符,这样你就可以直接分配给一个数量的实例,希望(祈祷)浮点数在正确的单位中。我的建议是你不要这样做,而是创建静态方法,如 等。float
Length::ofMeters( float )
Length::ofInches( float )
你的想法并不是全新的;这是在2001年左右提出的。
你的设计的主要问题是,做完全相同的事情。你们都可以将它们实现为Distance toInches(Distance);
Distance toMillimeters(Distance);
Distance toFoo(Distance bar) { return bar };
原因是.它们从字面上看是一样的.1 inch
2.54 mm
Distance
你可以得到的是,明显的实现是常数等于 2.54 毫米。float toInches(Distance d)
float toInches(Distance d) { return d/Distanche::inch; }
Distance::inch
这些类型必须是类,因为您需要模板参数数学。你真的需要在 SI 中做到这一点,因为速度=距离/持续时间。只有 SI 单位才足够理智。,并且只是 的 typedef 。Unit<m1,kg1,s1>/Unit<m2,kg2,s2>=Unit<m1-m2,kg1-kg2,s1-s2>
Distance
Unit<1,0,0>
由于你的变量描述了某种物理属性,我建议你自己为每个变量创建一个类型,C++ 最强大的功能之一是你可以定义自己的类型(OOP),然后你将在后台使用基本类型,并为它们提供转换等功能。 和重载运算符,例如,我使用我自己的类型 和 我重载运算符*,这样我就可以像这样将其乘以我的矩阵,因此还添加了功能,例如获取向量的长度。.toInches()
vector3d
vector3d operator*(const matrix3x3& mat)
unsigned int Length() const
评论
d.toInches();
toInches(d);
float
float_type
float_type
Distance d = 100; Time t = 1; Velocity v = d / t;
Velocity computeSpeed(Distance d, Time t);
computeSpeed( elapsedTime, metersWalked);