C ++模板数组大小扣除

时间:2018-01-17 08:31:45

标签: c++ arrays templates

我试图为编译器设计一种方法来推断作为非类型模板参数传递的数组的大小。

如果我明确地将数组大小作为第三个模板参数传递,那么我可以使模板工作,但这会将技​​术打开错误。

任何人都可以想到这样做的方法。 下面的代码不会编译,但它会让我知道我想要实现的目标。

// Compile time deduction of array size.
template <typename T, const size_t SIZE>
char(&array_size(T(&array)[SIZE]))[SIZE];

#define ARRAY_SIZE(x) (sizeof(array_size(x)))

template <typename T, T BEGIN[]>
struct Test
{
  enum
  {
    SIZE = ARRAY_SIZE(BEGIN)
  };
};

int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

int main()
{
  Test<int, a> test;

  return 0;
}

[编辑] 我忘了指出解决方案也必须兼容C ++ 03。

2 个答案:

答案 0 :(得分:3)

简单地

template <typename T, std::size_t N>
constexpr std::size_t array_size(const T(&)[N]) { return N; }

在C ++ 17中,您可以

template <auto V>
struct Test
{
    enum { SIZE = array_size(*V) };
};

Test<&a> test;

Demo

之前,你可能会做一个更详细的

template <typename T, T t>
struct Test
{
    enum { SIZE = array_size(*t) };
};

Test<decltype(&a), &a> test;

Demo(适用于gcc但不适用于clang: - /)

也适用于clang的版本:

template <typename T, std::size_t N>
constexpr std::integral_constant<std::size_t, N> array_size(const T(&)[N]) { return {}; }

template <typename T, T V>
struct Test
{
    enum { SIZE = decltype(array_size(*std::declval<T>()))::value };
};

Demo

答案 1 :(得分:-1)

C ++ 11在type_traits中引入了范围

#include <type_traits>
std::extent<decltype(a)>::value

计算模板参数的数组大小。 见http://en.cppreference.com/w/cpp/types/extent