6

I'm trying to devise a way for the compiler to deduce the size of an array passed as a non-type template parameter.

I can make the template work if I explicitly pass the array size as a third template parameter, but that opens the technique to errors.

Can anyone think of a way of doing this. The code below doesn't compile, but it gives an idea of what I'm trying to achieve.

// 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;
}

[EDIT] I forgot to point out that the solution must also be C++03 compatible.

2

2 Answers 2

5

Simply

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

In C++17, you may do

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

and

Test<&a> test;

Demo

Before, you may do a more verbose

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

and

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

Demo (works with gcc but not clang :-/)

Version which also works with 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

Sign up to request clarification or add additional context in comments.

5 Comments

Doesn't compile. "error C2101: '&' on constant" for enum { SIZE = array_size(*t) };
For C++17 version. "a parameter cannot have a type that contains 'auto'"
Note: I tried compiling with the C++ standard set to C++17
@JWellbelove: I added a demo link which works (I had a case typo) on gcc (but not on clang...). Which compiler do you use ?
Work-around found for clang too.
-2

C++11 introduced extent in type_traits

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

which evaluates to the array size of the template argument. See http://en.cppreference.com/w/cpp/types/extent

1 Comment

The SIZE is always defined as zero when I use this inside the template class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.