8

I'm studying new features provided by C++11 and I found std::remove_extent.

typedef std::remove_extent<int[24]>::type A; // A is int

However I can't find a usage for this, aside from defining a new type from an existing type by removing a dimension from the given type.

Could anyone suggest why C++11 introduced this feature? Is there any benefits of using it?

edmz
  • 8,220
  • 2
  • 26
  • 45
xuanyue
  • 1,368
  • 1
  • 17
  • 36
  • 2
    Why don't you search for "remove_extent"? On SO, there is e.g. [this answer](http://stackoverflow.com/a/10150181/) which makes use of `remove_extent`. – dyp Jul 25 '15 at 07:02
  • "I can't find a usage for this, aside from..." - what you mention there is the entire point of this, so you've just answered your question. More specifically, the type you're removing extent from could be hidden behind the `typedef`, or more commonly, a template parameter. – milleniumbug Jul 25 '15 at 07:09

2 Answers2

10

There is a good example of using std::remove_extent in the C++ Standard itself.

template function that creates an object of smart pointer std::unique_ptr

template <class T> unique_ptr<T> make_unique(size_t n);

returns the following expression (20.8.1.4 unique_ptr creation p.#4)

unique_ptr<T>(new remove_extent_t<T>[n]())

Consider for example declaration

auto p2 = std::make_unique<int[][10]>(2);

In this case make_unique need to remove dimension specified like [] in the type declaration int[][10] and substitute it for [2] getting int[2][10] in the new expression.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

When you work with arrays, you may need to get the total number of elements the array has including sub-arrays. This can be done with some template meta-programming, by using std::extent and std::rank along with std::remove_extent.

template <class T, std::size_t N = std::extent<T>::value >
struct total_elements 
{
    using M_type = typename std::remove_extent<T>::type;
    static constexpr std::size_t value = N * total_elements< M_type >::value;
};

template <class T>
struct total_elements<T, 0> : std::integral_constant<std::size_t, 1> {};

Live example.

This can be particularly useful if you work with vector of vectors because the storage is not guaranteed to be contiguous: by giving the total number of elements and a 1D vector, you will obtain that. You'll also need some pointer arithmetic to make it behave as if it were multidimensional, but that's easy to abstract in a class.


As a note, the standard does not obligate you to use it: if you find a place where it may be useful, then go for it.

edmz
  • 8,220
  • 2
  • 26
  • 45