【问题标题】:How to map the Enum template to type template?如何将枚举模板映射到类型模板?
【发布时间】:2021-08-11 15:26:50
【问题描述】:

我有一个模板函数,目前看起来像这样:

#include <string>

enum class Enum { EVENT_ONE, EVENT_TWO };

template<Enum e, typename T>
void MyFunc() { }

int main(int argc, const char* argv[])
{
    MyFunc<Enum::EVENT_ONE, int>();
    MyFunc<Enum::EVENT_TWO, std::string>();
}

我想在enum classtypename template 之间创建一些常量映射,以使其更简单。

理想情况下,此方法应仅获取枚举作为模板,并且类型名模板将使用预定义的映射以某种方式解析。

int main(int argc, const char* argv[])
{
    MyFunc<Enum::EVENT_ONE>();
    MyFunc<Enum::EVENT_TWO>();
}

在现代 C++(C++17 或 C++20)中是否可行?

【问题讨论】:

    标签: c++ templates enums c++17 typetraits


    【解决方案1】:

    您可以编写 enum_to_type 特征并相应地对其进行专门化:

    #include <string>
    
    enum class Enum { EVENT_ONE, EVENT_TWO };
    
    
    template <Enum e> struct enum_to_type;
    template <> struct enum_to_type<Enum::EVENT_ONE> { using type = int; };
    template <> struct enum_to_type<Enum::EVENT_TWO> { using type = std::string; };
    // ... maybe more specializations ...
    
    
    template<Enum e>
    void MyFunc() {
        using T = typename enum_to_type<e>::type;
    }
    
    int main(int argc, const char * argv[]) {
        MyFunc<Enum::EVENT_ONE>();
        MyFunc<Enum::EVENT_TWO>();
    }
    

    除了作用域枚举之外,这在 C++98 中应该已经可以了。从 C++11 开始,您可以使用别名模板为它增添趣味:

    template <Enum e>
    using enum_to_type_t = typename enum_to_type<e>::type;
    

    这将在使用 trait 时减少混乱的语法:

    void MyFunc() {
        using T = enum_to_type_t<e>;
    }
    

    【讨论】:

      【解决方案2】:

      既然你要求,你可以使用if constexpr如下。

      #include <string>
      
      enum struct Enum { EVENT_ONE, EVENT_TWO };
      
      template<Enum e>
      constexpr auto get_type_from_enum() noexcept
      {
          if constexpr (e == Enum::EVENT_ONE) return int{};
          else if constexpr (e == Enum::EVENT_TWO) return std::string{};
          // ...  more like this ..
      }
      // type alias for the enum type
      template<Enum e> using get_type_from_enum_t = decltype(get_type_from_enum<e>());
      
      template<Enum e> void MyFunc() 
      {
          using T = get_type_from_enum_t<e>;
          // ... Do something with T
      }
      

      不同于传统的专业化方法。 (See Live Demo)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-24
        • 2018-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-09
        相关资源
        最近更新 更多