C++中重载浮点类型的有效方法?

swvgeqrz  于 2023-05-08  发布在  其他
关注(0)|答案(3)|浏览(174)

我想存储数量,如重量,时间,长度。我认为这种方式更易读,避免了这样的函数不匹配:

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
  • 这可能会影响效率

是否可以将“转换”常量方法添加到数值类型?附带问题:这种做法是不好还是矫枉过正?
注意:我用C++03卡住了:(

lvjbypge

lvjbypge1#

你的想法并不是全新的;这项建议是在2001年左右提出的。
你的设计的主要问题是Distance toInches(Distance);Distance toMillimeters(Distance);做的是完全相同的事情。您可以将它们都实现为Distance toFoo(Distance bar) { return bar };
原因是1 inch * 是 * 2.54 mm。它们实际上是相同的Distance
你 * 可以 * 得到的是float toInches(Distance d),明显的实现是float toInches(Distance d) { return d/Distanche::inch; },其中Distance::inch是一个等于2.54 mm的常数。
这些类型必须是类,因为您需要模板参数数学。你真的需要在SI中这样做,因为速度=距离/持续时间。只有SI单位才足够健全。Unit<m1,kg1,s1>/Unit<m2,kg2,s2>=Unit<m1-m2,kg1-kg2,s1-s2>,而Distance只是Unit<1,0,0>的typedef。

dced5bon

dced5bon2#

我已经在C#中完成了你想做的事情,C#的重载能力比C少得多。结果是令人敬畏的,因为它保护您不受各种错误的影响,并保持代码简洁和中肯。(它消除了 * 偶然的复杂性 *。
它还允许IDE的完成建议功能发挥作用,因为它将向您展示您可以对每个变量执行哪些操作,而不必记住哪些全局范围函数适用于每个变量。
实现的方法是为每种不同类型的数量声明一个新类,该类包含一个以某种标准单位表示的值。(当然,您会为您的标准单位选择SI系统,对吗?)
一旦有了这些类,就可以重载所有适用的操作符,以便它们在每个类的示例之间以及在每个有意义的组合之间工作。
如果你喜欢冒险的生活,你甚至可以使用C
的惊人能力来重载类型转换运算符,这样你就可以直接将float赋值给一个数量的示例,希望(祈祷)浮点数是正确的单位。我的建议是不要这样做,而是创建静态方法,如Length::ofMeters( float )Length::ofInches( float )等。

4ioopgfo

4ioopgfo3#

由于你的变量描述了某种物理属性,我建议你为每个变量创建一个类型,C++最强大的功能之一是你可以定义自己的类型(OOP),然后你将在后台使用基本类型,并为它们提供功能,如转换。.toInches()和重载运算符,例如我使用我自己的vector3d类型,我重载了运算符 *,这样我就可以将它乘以一个矩阵,像这样vector3d operator*(const matrix3x3& mat)还添加了unsigned int Length() const这样的函数来获得向量的长度。

相关问题