使用 auto 声明非类型模板参数

在 C++ 17 之前,当编写模板非类型参数时,必须首先指定其类型。所以一个常见的模式变成了类似的东西:

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

using five = integral_constant<int, 5>;

但对于复杂的表达式,使用类似的东西需要在实例化模板时编写 decltype(expr), expr。解决方案是简化这个习惯用法并简单地允许 auto

Version >= C++ 17

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

using five = integral_constant<5>;

为 unique_ptr 清空自定义删除器

一个很好的激励示例可以来自尝试将空基础优化与 unique_ptr 的自定义删除器相结合。不同的 C API 删除器具有不同的返回类型,但我们并不关心 - 我们只是希望某些功能适用于任何功能:

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

现在你可以简单地使用任何函数指针,它可以将 T 类型的参数作为模板非类型参数,而不管返回类型如何,并获得一个无大小的开销 unique_ptr

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