# 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;