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