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