Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to extract array size from a template argument?

If this is a duplicate I apologize. I looked around and found similar issues but nothing exactly like this.

If I instantiate a template like so...

MyClass<int[10]> c;

How can I write the template to get access to both the type and the array size? I've tried everything I can think of and I can't get it.

I was inspired by the std::function template which lets you use similar syntax to the function prototype, like...

std::function<int(MyClass&)> myfunc;

So I thought it would be nice to have something similar for the array and its size. I can use any of the newest c++ features (c++ 11/14).

like image 292
extracrispy Avatar asked Jun 01 '15 15:06

extracrispy


People also ask

What is a template argument for a template parameter?

A template argument for a type template parameter must be a type-id, which may name an incomplete type: A template argument for a template template parameter must be an id-expression which names a class template or a template alias. When the argument is a class template, only the primary template is considered when matching the parameter.

What are the requirements for a template argument during instantiation?

For integral and arithmetic types, the template argument provided during instantiation must be a converted constant expression of the template parameter's type (so certain implicit conversion applies).

What is the difference between a function template and a parameter pack?

In a function template, there are no restrictions on the parameters that follow a default, and a parameter pack may be followed by more type parameters only if they have defaults or can be deduced from the function arguments.

How are the arguments of a function template interpreted?

For function templates, the arguments are explicitly provided, deduced from the context, or defaulted. If an argument can be interpreted as both a type-id and an expression, it is always interpreted as a type-id, even if the corresponding template parameter is non-type:


Video Answer


3 Answers

You can add a partial specialization which looks like this:

template <typename T, ptrdiff_t N>
class MyClass<T[N]>
{
};

Here's a demo.

like image 130
Pradhan Avatar answered Nov 15 '22 22:11

Pradhan


template<class Arr>
struct array_size {};
template<class T, size_t N>
struct array_size<T[N]>:std::integral_constant<std::size_t, N>{};
template<class Arr>
struct array_element {};
template<class Arr>
using array_element_t = typename array_element<Arr>::type;
template<class T, size_t N>
struct array_element<T[N]>{using type=T;};

now you can array_size<ArrType>{} and array_element_t<ArrType> without unpacking the type.

like image 24
Yakk - Adam Nevraumont Avatar answered Nov 15 '22 23:11

Yakk - Adam Nevraumont


template <typename T, typename = void>
struct deduce
{
};

template <typename T>
struct deduce<T,
  typename ::std::enable_if<
    ::std::is_array<T>{}
  >::type
>
{
  using value_type =
    typename ::std::decay<decltype(::std::declval<T>()[0])>::type;

  static constexpr auto size = sizeof(T) / sizeof(value_type);
};
like image 32
user1095108 Avatar answered Nov 15 '22 22:11

user1095108