<legend id='M8m87'><style id='M8m87'><dir id='M8m87'><q id='M8m87'></q></dir></style></legend>
<i id='M8m87'><tr id='M8m87'><dt id='M8m87'><q id='M8m87'><span id='M8m87'><b id='M8m87'><form id='M8m87'><ins id='M8m87'></ins><ul id='M8m87'></ul><sub id='M8m87'></sub></form><legend id='M8m87'></legend><bdo id='M8m87'><pre id='M8m87'><center id='M8m87'></center></pre></bdo></b><th id='M8m87'></th></span></q></dt></tr></i><div id='M8m87'><tfoot id='M8m87'></tfoot><dl id='M8m87'><fieldset id='M8m87'></fieldset></dl></div>

  • <small id='M8m87'></small><noframes id='M8m87'>

  • <tfoot id='M8m87'></tfoot>

          <bdo id='M8m87'></bdo><ul id='M8m87'></ul>

        C++11 类型特征来区分枚举类和常规枚举

        时间:2023-05-24
        <legend id='iB02G'><style id='iB02G'><dir id='iB02G'><q id='iB02G'></q></dir></style></legend>

        <small id='iB02G'></small><noframes id='iB02G'>

            <bdo id='iB02G'></bdo><ul id='iB02G'></ul>
              <tfoot id='iB02G'></tfoot>
              <i id='iB02G'><tr id='iB02G'><dt id='iB02G'><q id='iB02G'><span id='iB02G'><b id='iB02G'><form id='iB02G'><ins id='iB02G'></ins><ul id='iB02G'></ul><sub id='iB02G'></sub></form><legend id='iB02G'></legend><bdo id='iB02G'><pre id='iB02G'><center id='iB02G'></center></pre></bdo></b><th id='iB02G'></th></span></q></dt></tr></i><div id='iB02G'><tfoot id='iB02G'></tfoot><dl id='iB02G'><fieldset id='iB02G'></fieldset></dl></div>

                    <tbody id='iB02G'></tbody>

                  本文介绍了C++11 类型特征来区分枚举类和常规枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  限时送ChatGPT账号..

                  我正在编写类似于 boost::promote 的促销模板别名,但适用于 C++11.这样做的目的是避免在从可变函数中检索参数时出现警告.例如

                  I'm writing a promotion template alias similar to boost::promote but for C++11. The purpose of this is to avoid warnings when retrieving arguments from varidic functions. e.g.

                  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;
                  }
                  

                  Promote 模板别名在可变参数的默认参数提升之后提升类型:1) 小于 int 的整数被提升为 int2) 浮点数提升为双倍

                  The Promote template alias promotes the type following the default argument promotion for variadic arguments: 1) An integer that's smaller than an int is promoted to int 2) A float is promoted to double

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

                  My problem is that a standard C++ enum can be promoted but a C++11 enum class is not promoted (compiler does not generate a warning). I want Promote to work with a regular enum but ignore a C++11 enum class.

                  如何区分我的提升模板别名中的枚举类和枚举?

                  How can I tell the difference between an enum class and an enum in my Promote template alias?

                  推荐答案

                  这是一个可能的解决方案:

                  Here is a possible solution:

                  #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 段中指定的作用域枚举和非作用域枚举之间的行为差​​异:

                  The solution exploits a difference in behavior between scoped and unscoped enumerations specified in Paragraph 7.2/9 of the C++11 Standard:

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

                  The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion (4.5). [...] Note that this implicit enum to int conversion is not provided for a scoped enumeration. [...]

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

                  Here is a demonstration of how you would use it:

                  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!");
                  }
                  

                  这是一个现场示例.

                  致谢:

                  感谢 Daniel Frey 指出我之前的方法只有在没有用户时才有效-operator + 的定义重载.

                  Thanks to Daniel Frey for pointing out that my previous approach would only work as long as there is no user-defined overload of operator +.

                  这篇关于C++11 类型特征来区分枚举类和常规枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:C++ 模板在 .h 中声明,在 .hpp 中定义 下一篇:C++ 中类与函数的模板类型推导?

                  相关文章

                  最新文章

                    <tfoot id='Mi8Pg'></tfoot>
                    <legend id='Mi8Pg'><style id='Mi8Pg'><dir id='Mi8Pg'><q id='Mi8Pg'></q></dir></style></legend>

                    1. <small id='Mi8Pg'></small><noframes id='Mi8Pg'>

                      <i id='Mi8Pg'><tr id='Mi8Pg'><dt id='Mi8Pg'><q id='Mi8Pg'><span id='Mi8Pg'><b id='Mi8Pg'><form id='Mi8Pg'><ins id='Mi8Pg'></ins><ul id='Mi8Pg'></ul><sub id='Mi8Pg'></sub></form><legend id='Mi8Pg'></legend><bdo id='Mi8Pg'><pre id='Mi8Pg'><center id='Mi8Pg'></center></pre></bdo></b><th id='Mi8Pg'></th></span></q></dt></tr></i><div id='Mi8Pg'><tfoot id='Mi8Pg'></tfoot><dl id='Mi8Pg'><fieldset id='Mi8Pg'></fieldset></dl></div>
                      • <bdo id='Mi8Pg'></bdo><ul id='Mi8Pg'></ul>