Выбор размера массива на основе аргумента шаблона в C ++ 11? - PullRequest
1 голос
/ 24 июня 2019

Рассмотрим этот код:

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 значений (Type1, Type2), я бы хотел, чтобы the_length имел значение 10, если T==Type1, и значение 20, если T==Type2.Можно ли это сделать в C ++ 11?Спасибо

Ответы [ 3 ]

4 голосов
/ 24 июня 2019

Что не так со старым добрым троичным оператором?

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

Если T является typename, а не значением какого-либо типа, вам нужно только изменить тест

template <typename T>
int function()
{
  std::array<T, std::is_same<SomeType1, T>::value ? 10u : 20u> x;
}
2 голосов
/ 24 июня 2019

Как сказал @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;
}
0 голосов
/ 24 июня 2019

Конечно, это возможно.Вам просто нужен другой уровень косвенности.Вот один из способов сделать это:

/* 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 helper struct принимает в качестве входных данных EnumType, а затем выводит другой тип массива в зависимости от того, что он находит.

...