5

我正在寻找使用 C++03 标准的解决方案(我被限制使用该版本的标准已有好几年了)。也欢迎 C++11 的解决方案,但不会被“接受”作为这个问题的答案。

什么是一种简单、简洁的方法,我可以将一组相关的常量浮点值表示为单个类型(类似于枚举)以确保类型安全而不会产生大量开销,并且仍然允许我直接将值作为浮点数进行操作?

最终结果是我希望能够执行以下操作:

enum FloatingPointEnum
{
   VALUE1 = 0.1234f,
   ...
   VALUEN = 0.6789f
};


float SomeFunction(FloatingPointEnum value)
{
    float new_value;
    /* perform some operation using "value" to calculate "new_value" */
    new_value = static_cast<float>(value); // <- a simplistic example
    return new_value;
}

虽然我可以想到几种解决方案,但它们都不像我想要的那样干净/简单/直截了当,而且我认为有人必须已经有了一个优雅的解决方案来解决这个问题(但我似乎无法在搜索中找到一个)。

编辑:

我希望使用未直接指定为枚举类型中的值的值对 SomeFunction 的以下调用无法编译:

float nonEnumeratedValue = 5.0f
SomeFunction(nonEnumeratedValue);
4

3 回答 3

8

有人必须已经有一个优雅的解决方案来解决这个问题

有很多问题没有优雅的解决方案(还有很多根本没有解决方案)。是什么让你认为这个问题有一个?这个假设是非常错误的。您可以获得的最接近的是使用包装类。

class FloatingPointEnum {
    float f;
    FloatingPointEnum(float arg) : f(arg) {}
public:
    static const FloatingPointEnum Value1;
    static const FloatingPointEnum Value2;
    operator float() const { return f; }
};
const FloatingPointEnum FloatingPointEnum::Value1(0.1234f);
const FloatingPointEnum FloatingPointEnum::Value2(0.6789f);
于 2013-10-16T16:10:25.073 回答
5

一种可能的替代解决方案,并不总是适用但非常干净,是使用固定精度。

让我们想象一下,您的枚举包含一些以米为单位的距离

enum DistancesMeter{
 A = 0.25,
 b = 0.05,
};

那么你可以简单地切换到使用 mm

enum DistancesMM{
 A = 250,
 b = 50,
};
于 2018-10-19T09:10:51.323 回答
2

在 C++11 中,您可以使用它constexpr来实现您想要的。

constexpr- 指定变量或函数的值可以出现在常量表达式中

http://en.cppreference.com/w/cpp/language/constexpr

constexpr您一起定义编译时常量。这仅适用于文字类型,例如float. 因为同时我们想要

float nonEnumeratedValue = 5.0f;
SomeFunction(nonEnumeratedValue);

要失败,我们不能使用简单的typedef. 相反,我们使用 Boost 的BOOST_STRONG_TYPEDEF.

#include <boost/serialization/strong_typedef.hpp>

BOOST_STRONG_TYPEDEF(float, FloatingPointEnum);
constexpr float VALUE1 = 0.1234f;
constexpr float VALUEN = 0.6789f;

float SomeFunction(FloatingPointEnum value)
{
  float new_value;
  /* perform some operation using "value" to calculate "new_value" */
  new_value = static_cast<float>(value); // <- a simplistic example
  return new_value;
}

现在您只能使用FloatingPointEnum. 不幸的是,实例化语法不再那么好

FloatingPointEnum f {VALUEN};

或者,您可以简单地使用 D 编程语言,其中支持浮点枚举并且以下代码按预期工作:

enum FloatingPointEnum
{
   VALUE1 = 0.1234f,
   //...
   VALUEN = 0.6789f
};


float SomeFunction(FloatingPointEnum value)
{
    float new_value;
    new_value = value; // No cast needed, welcome to D!
    return new_value;
}

调用SomeFunction结果float

Error: function test.SomeFunction (FloatingPointEnum value) is not callable using argument types (float)
于 2017-02-06T22:32:45.620 回答