Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The use of T[] as a template parameter

Tags:

I've recently stumbled upon the use of unique_ptr<T[]>, where I understand that the aim is to delete the pointer with delete[].

What puzzles me is that unique_ptr<T[3]> is instead invalid (correct me if I'm wrong).

What is the type of T[] in the template? How is it different from T[3]? These are arrays, so shouldn't they be the same? Is there any other use of T[] as a type in templates?

like image 652
Costantino Grana Avatar asked Jan 09 '18 11:01

Costantino Grana


People also ask

What is the purpose of template parameter?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Which is correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.

How do you use template arguments in C++?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

What is Nontype parameter?

A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members.


1 Answers

T[] is a type. It's the type "array of unknown bound of T". It is an incomplete type.

T[3] is also a type. It's the type "array of 3 T". It is a different type from T[], just like int and double are different types.

The default_delete template is specialized partially for incomplete arrays of the form T[]. However, the complete-array types like T[3] are forbidden, since that would be very confusing: the unique_ptr cannot tell how long your array is, since it only handles the array through a pointer to its first element.

(There are technical details in the mechanics: The specialization default_delete<T[3]> isn't actively prohibited, but since its call operator expects a T(*)[3], it will generally not match the pointer that comes from the unique_ptr, and even if the call were well-formed, a delete expression on such a pointer is not allowed (= has undefined behaviour). You "cannot delete arrays" if you will, you can only "delete[] arrays via size-erased pointers".)

Note that the make_unique function template is actively deleted for complete array types.

Curiously, for make_shared the committee went down a different route and allows complete array types. To do so, shared_ptr<T[N]> has a precondition that you only construct it from a matching new T[N] (though that's not checkable in general). (I've never quite understood why that was a good idea.)

like image 65
Kerrek SB Avatar answered Sep 20 '22 09:09

Kerrek SB