【问题标题】:How to specialize a value template with multiple enum values如何专门化具有多个枚举值的值模板
【发布时间】:2022-01-15 22:16:09
【问题描述】:

如果我有以下代码,这是一个带有值模板的结构,

enum FakeEnum
{
    FakeNone,
    Fake1,
    Fake2,
    Fake3,
    Fake4,
    Fake5,
    Fake6,
    Fake7,
    Fake8,
    Fake9,
    Fake10,
    Fake11,
    Fake12,
    Fake13,
    Fake14,
    Fake15,
    Fake16,
    Fake17,

    // ...

    Fake100,
};

template<FakeEnum FE>
struct FakeStruct
{
    void FakeIt();
};

template<FakeEnum FE>
void FakeStruct<FE>::FakeIt()
{
    std::cout << "void FakeStruct<" << FE << ">::FakeIt()";
}

template<>
void FakeStruct<Fake12>::FakeIt()
{
    std::cout << "specialized on Fake12";
}

template<>
void FakeStruct<Fake14>::FakeIt()
{
    std::cout << "specialized on Fake14";
}

template<>
void FakeStruct<Fake23>::FakeIt()
{
    std::cout << "specialized on Fake23";
}

...

...但我真正想写的是类似的东西

template<>
void FakeStruct<Fake12 || Fake13 || Fake14 or how do I do this???>::FakeIt()
{
    std::cout << "specialized on Fake12, Fake13, and Fake14";
}

是否有某种类似于 SFINAE 的方式来编写 FakeStruct&lt;&gt;::FakeIt() 特化而不为多个枚举值重复它?理想情况下不改变FakeStruct的原始声明/签名?

【问题讨论】:

    标签: c++ templates sfinae


    【解决方案1】:

    使用requires:

    #include <iostream>
    
    enum E {a, b, c, d};
    
    template <E Value>
    struct A
    {
        void foo()
        {
            std::cout << "0\n";
        }
    };
    
    template <E Value> requires (Value == b || Value == c) // or `Value >= b && value <= c`
    struct A<Value>
    {
        void foo()
        {
            std::cout << "1\n";
        }
    };
    
    int main()
    {
        A<a>{}.foo(); // 0
        A<b>{}.foo(); // 1
        A<c>{}.foo(); // 1
        A<d>{}.foo(); // 0
    }
    

    【讨论】:

      【解决方案2】:

      我会使用 if constexpr,它仍然是元模板编程,但看起来很像普通的 c++。

      #include <type_traits>
      #include <iostream>
      
      enum class FakeEnum // <= don't forget class here
      {
          FakeNone,
          Fake1,
          Fake2,
          Fake3,
          Fake4,
          Fake5
      };
      
      template<FakeEnum E>
      void FakeIt()
      {
          // you now can make sprecializations using "if constexpr"
          if constexpr ((E == FakeEnum::Fake2) || (E == FakeEnum::Fake3) || (E == FakeEnum::Fake4))
          {
              // functionality here or call another function if needed
              std::cout << "2 Or 3 Or 4\n";
          }
          else
          {
              std::cout << "1 or 5\n";
          }
      }
      
      
      int main()
      {
          FakeIt<FakeEnum::Fake1>();
          FakeIt<FakeEnum::Fake5>();
          FakeIt<FakeEnum::Fake3>();
          
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多