# Declaring non-type template arguments with auto

suggest changePrior to C++17, when writing a template non-type parameter, you had to specify its type first. So a common pattern became writing something like:

```
template <class T, T N>
struct integral_constant {
using type = T;
static constexpr T value = N;
};
using five = integral_constant<int, 5>;
```

But for complicated expressions, using something like this involves having to write `decltype(expr), expr`

when instantiating templates. The solution is to simplify this idiom and simply allow `auto`

:

```
template <auto N>
struct integral_constant {
using type = decltype(N);
static constexpr type value = N;
};
using five = integral_constant<5>;
```

### Empty custom deleter for std::unique_ptr

A nice motivating example can come from trying to combine the empty base optimization with a custom deleter for `unique_ptr`

. Different C API deleters have different return types, but we donâ€™t care - we just want something to work for any function:

```
template <auto DeleteFn>
struct FunctionDeleter {
template <class T>
void operator()(T* ptr) const {
DeleteFn(ptr);
}
};
template <T, auto DeleteFn>
using unique_ptr_deleter = std::unique_ptr<T, FunctionDeleter<DeleteFn>>;
```

And now you can simply use any function pointer that can take an argument of type `T`

as a template non-type parameter, regardless of return type, and get a no-size overhead `unique_ptr`

out of it:

`unique_ptr_deleter<std::FILE, std::fclose> p;`