【问题标题】:Choosing an array size based on a template argument in C++11?在 C++11 中根据模板参数选择数组大小?
【发布时间】:2019-06-23 23:13:35
【问题描述】:

考虑这段代码:

enum class EnumType
{
  Type1,
  Type2
};

constexpr std::size_t the_length;

template <EnumType T>
int function()
{
  std::array<uint8_t, the_length> x;
  //some code here that uses x 
}

我希望数组x 的长度根据T 的类型具有不同的值。例如,如果 T 可以取 2 个值之一(Type1Type2),我希望 the_length 如果 T==Type1 具有值 10,如果 T==Type2 具有值 20。这可以在 C++11 中完成吗?谢谢

【问题讨论】:

  • “如果T 可以取两个值”是什么意思?
  • 你的意思是template&lt;typename T&gt; 吗?
  • 包含一个您想象的呼叫站点外观的示例可能会有所帮助
  • 看起来T 有时用作EnumType 类型的枚举类型(在参数列表中),有时用作类型名(在std::array 的参数列表中)。你能澄清一下吗?
  • @astrophobia 你不能使用T 作为std::array 的第一个模板参数。 T 是一个枚举器,但该参数必须是类型名称

标签: c++ c++11 templates template-meta-programming


【解决方案1】:

旧的三元运算符有什么问题?

template <EnumType T>
int function()
{
  std::array<SomeType, T == EnumType::Type1 ? 10u : 20u> x;
}

如果Ttypename,而不是某种类型的值,您只需更改测试

template <typename T>
int function()
{
  std::array<T, std::is_same<SomeType1, T>::value ? 10u : 20u> x;
}

【讨论】:

    【解决方案2】:

    正如@templatetypedef 所说,但 C++11 可以做的远不止这些:

    #include <array>
    #include <cstddef>
    
    enum class EnumType { T1, T2 };
    
    template<EnumType T>
    struct my_array_traits;
    
    template<>
    struct my_array_traits<EnumType::T1> {
        using type = float;
        constexpr static std::size_t value = 5;
    };
    
    template<>
    struct my_array_traits<EnumType::T2> {
        using type = double;
        constexpr static std::size_t value = 10;
    };
    
    template<EnumType T>
    struct my_other_array_traits;
    
    template<>
    struct my_other_array_traits<EnumType::T1> {
        using type = short;
        constexpr static std::size_t value = 20;
    };
    
    template<>
    struct my_other_array_traits<EnumType::T2> {
        using type = long;
        constexpr static std::size_t value = 40;
    };
    
    
    template <EnumType T, template<EnumType> class array_traits>
    int function()
    {
        std::array<typename array_traits<T>::type,
                   array_traits<T>::value> x;
        //some code here that uses x 
        return 0;
    }
    
    int main() {
        function<EnumType::T1, my_array_traits>();
        function<EnumType::T2, my_array_traits>();
        function<EnumType::T1, my_other_array_traits>();
        function<EnumType::T2, my_other_array_traits>();
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      当然,这是可能的。您只需要另一个级别的间接性。这是执行此操作的一种方法:

      /* array_for<T>::type gives you your array type. */
      template <EnumType T> struct array_for;
      
      /* Specialize to give different values based on what T is. */
      template <> struct array_for<Option1> {
          using type = std::array<WhateverTypeYouWantToUse1, 10>;
      };
      template <> struct array_for<Option2> {
          using type = std::array<WhateverTypeYouWantToUse2, 20>;
      };
      
      template <EnumType T>
      int function()
      {
        typename array_for<T>::type myArray;
        /* do whatever coding dance with myArray seems most fitting. */
      }
      

      这里,array_for 帮助器 struct 模板将 EnumType 作为输入,然后根据找到的内容输出不同类型的数组。

      【讨论】:

      • 您可以指定变量模板(C++14 起),无需包装结构
      • @M.M 我相信 OP 的问题专门针对 C++11。
      猜你喜欢
      • 2017-09-27
      • 1970-01-01
      • 2011-03-10
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      • 2012-12-31
      相关资源
      最近更新 更多