gpt4 book ai didi

C++ 将浮点值转换为枚举 - 但不是 VS 2010

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:18 27 4
gpt4 key购买 nike

我有一些模板代码适用于 Xcode 4.5 和 LLVM 3.0,但适用于 VS 2010 Express C++ 工具链 (v 10.0.30319.1)。

我正在使用我无法控制的第三方 API。它以只能由 API 函数解释的黑盒“blob”形式为我的代码提供值:

// API_Secret is a black-box encapsulation of a floating-point number or a boolean value.
// It is provided by a third-party API, with associated access functions.
// For all intents and purposes, it's a complete black box.
// This enum represents the internal 'type' of a secret value.
enum API_SecretTypeEnum {
API_Number,
API_Boolean,
};
// Other API declarations:
API_SecretTypeEnum API_GetType(const API_Secret &value);
double API_AsNumber(const API_Secret &value);
bool API_AsBoolean(const API_Secret &value);

// my code:
template <typename ValueType>
class Extractor {
public:
ValueType extract(API_Secret value) {
if (API_GetType(value) == API_Number) {
return static_cast<ValueType>(API_AsNumber(value));
} else if (API_GetType(value) == API_Boolean) {
return API_AsBoolean(value) ? ValueType(1) : ValueType(0);
}
return ValueType();
}
};

// boolean specialization - not 100% sure it's needed though
template<>
class Extractor <bool> {
public:
bool extract(API_Secret value) {
return API_AsBoolean(value);
}
};

然后,稍后:

API_Secret API_GetSomeValue(int some_sort_of_handle);

// get some black-box values from the API
API_Secret secret0 = API_GetSomeValue(0);
API_Secret secret1 = API_GetSomeValue(1);
API_Secret secret2 = API_GetSomeValue(2);

// for certain external reasons we expect this to be an integer representation:
Extractor<int> e0;
int v0 = e0.extract(secret0);

// for certain external reasons we expect this to be a double representation:
Extractor<double> e1;
double v1 = e1.extract(secret1);

// for certain external reasons we expect this to be a boolean representation:
Extractor<bool> e2;
bool v2 = e2.extract(secret2);

现在了解 Xcode、LLVM 和 VS 2010 之间的区别。在 Xcode 和 LLVM 中,将编译以下内容(作为完整程序的一部分):

enum MyEnum {
Enum0,
Enum1,
};
Extractor<MyEnum> ee;
MyEnum ve = ee.extract(secret0);

即类模板使用 static_cast 将 float 转换为枚举。这似乎工作正常,this page 的解释部分表明这是有效的:

8) Integer, floating-point, or enumeration type can be converted to any enumeration type (the result is unspecified if the value of expression, converted to the enumeration's underlying type, is not one of the target enumeration values)

但是使用VS2010,会遇到如下编译错误:

error C2440: 'static_cast' : cannot convert from 'double' to 'MyEnum'

     Conversions between enumeration and floating point values are no longer allowed

还有这个MSDN article似乎通过不提及浮点类型并明确声明“整数”值来证实这一点:

The static_cast operator can explicitly convert an integral value to an enumeration type. If the value of the integral type does not fall within the range of enumeration values, the resulting enumeration value is undefined.

因此,VS 2010 和其他编译器之间似乎存在显着差异。我想知道这是否可以在 VS 2010 中绕过?它是 VS 2010 根本不支持的语言的新功能吗?但是我对此进行了查询,因为错误消息显示“不再允许”,这意味着它已被明确禁止。

我知道一个解决方法 - 我可以使用 Extractor<MyEnum> 而不是转换为枚举(使用 Extractor<int> )相反,然后简单地将其分配给目标 MyEnum 变量。然而,这个模板实际上用作调用包装函数的更大系统的一部分,在这种情况下,包装函数采用 MyEnum 值。这会阻止模板正确匹配,因为 ValueType 参数实际上是从包装函数的签名中自动获取的。

或者,是否可以编写一个匹配 enum 的 Extractor 模板特化?只有类型?然后我可以先转换为整数类型。或者也许基本模板总是可以首先转换为 int,然后我可以编写一个不这样做的浮点特化 - 但我不确定如何编写一个捕获所有浮点类型的模板(float,双,...)。

最佳答案

我很确定Visual Studio-2010 supports <type_traits> .您可以使用 std::enable_if连同 std::is_enum .

template <typename ValueType, typename Enable = void>
class Extractor {
public:
ValueType extract(API_Secret value);
};

template <typename ValueType>
class Extractor<ValueType, typename std::enable_if<std::is_enum<ValueType>::value>::type>
{
...
};


您可以使用 std::is_floating_point 来匹配浮点类型。 .

关于C++ 将浮点值转换为枚举 - 但不是 VS 2010,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14821846/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com