当前位置: 首页 > 知识库问答 >
问题:

区分枚举类和常规枚举的C11型特征

闾丘诚
2023-03-14

我正在为C 11编写一个类似于boost::promote的升级模板别名。这样做的目的是在从变量函数检索参数时避免出现警告。例如

template <typename T>
std::vector<T> MakeArgVectorV(int aArgCount, va_list aArgList)
{
    std::vector<T> args;
    while (aArgCount > 0)
    {
        args.push_back(static_cast<T>(va_arg(aArgList, Promote<T>)));
        --aArgCount;
    }
    return args;
}

提升模板别名提升了变量参数的默认参数提升后的类型: 1)小于int的整数提升为int 2)浮点提升为双

我的问题是,可以提升标准C枚举,但不能提升C 11枚举类(编译器不会生成警告)。我希望升级使用常规枚举,但忽略C 11枚举类。

如何区分枚举类和枚举在我的推广模板别名?

共有2个答案

林威
2023-03-14

似乎从C 23开始,@AndyProwl提供的类似解决方案将可从type\ U TRATIES获得

#include <type_traits>

enum E { a, b };
enum class Es { x, y, z };

std::is_scoped_enum_v<E>;  // False
std::is_scoped_enum_v<Es>; // True
张建树
2023-03-14

这里有一个可能的解决方案:

#include <type_traits>

template<typename E>
using is_scoped_enum = std::integral_constant<
    bool,
    std::is_enum<E>::value && !std::is_convertible<E, int>::value>;

该解决方案利用了C 11标准第7.2/9段中指定的作用域枚举和非作用域枚举之间的行为差异:

枚举数或非范围枚举类型的对象的值通过整数提升(4.5)转换为整数。[...] 请注意,没有为作用域枚举提供此隐式枚举到int的转换。[...]

以下是您将如何使用它的演示:

enum class E1 { };
enum E2 { };
struct X { };

int main()
{
    // Will not fire
    static_assert(is_scoped_enum<E1>::value, "Ouch!");

    // Will fire
    static_assert(is_scoped_enum<E2>::value, "Ouch!");

    // Will fire
    static_assert(is_scoped_enum<X>::value, "Ouch!");
}

这是一个活生生的例子。

鸣谢:

感谢丹尼尔·弗雷指出,我以前的方法只有在没有用户定义的运算符重载的情况下才有效。

 类似资料:
  • 问题内容: Enumeration <有区别吗?扩展ZipEntry>和Enumeration ?如果是这样,有什么区别? 问题答案: 拥有其中一种后,您在做什么上没有实际差异,因为type参数仅在“输出”位置使用。另一方面,在您可以 用作 其中一个的方面有很大的不同。 假设您有一个-您无法将其传递给作为其参数之一的方法。您 可以 将其传递给采用方法。 当您有一个在输入和输出位置都使用type参数

  • 问题内容: 枚举具有获取枚举常量的方法,并且在具有 我发现的名称的类中存在的相同类型的方法都给出相同的输出。那还有什么其他区别。如果没有区别,那么为什么要添加JSL ? 问题答案: 包括该方法的原因是它可以与任何方法一起使用。相比之下, 用于特定方法的方法仅适用于该特定方法…,因为类不能被多态使用。 显然,该方法仅在您实现 需要 针对多种类型使用的代码的情况下才真正有用……而泛型则不会削减它。

  • 问题内容: 例如,我该怎么做: 结果示例: 问题答案: 迅捷4.2+ 从Swift 4.2(使用Xcode 10)开始,只需添加协议一致性即可从中受益。要添加此协议一致性,您只需要在某处写: 如果枚举是您自己的,则可以直接在声明中指定一致性: 然后,以下代码将打印所有可能的值: 与早期Swift版本(3.x和4.x)的兼容性 如果您需要支持Swift 3.x或4.0,则可以通过添加以下代码来模仿S

  • 枚举类(“新的枚举”/“强类型的枚举”)主要用来解决传统的C++枚举的三个问题: 传统C++枚举会被隐式转换为int,这在那些不应被转换为int的情况下可能导致错误 传统C++枚举的每一枚举值在其作用域范围内都是可见的,容易导致名称冲突(同名冲突) 不可以指定枚举的底层数据类型,这可能会导致代码不容易理解、兼容性问题以及不可以进行前向声明 枚举类(enum)(“强类型枚举”)是强类型的,并且具有类

  • 问题内容: 假设是,我将如何产生给定序数的枚举值? 问题答案: 足够了。一条线; 足够简单。

  • 例如,我如何做类似的事情: 结果示例: