C草的编译期编程:元模版
type
status
date
slug
summary
tags
category
icon
password
Property
Sep 12, 2025 03:46 AM
最近一直在写time-devourer这个项目,我的多态设计的强迫症又犯了,不可避免和元模版打交道了。这篇文章简单的稍微讲一下我遇到的几个场景。
自动包装COM对象指针,生命周期结束自动调用Release。要求T必须能调用Release方法,且T必须是IUnknown的子类。
头一次写模版元编程给我肘晕了,这就是编译期编程么,害怕.
这里稍微总结一下几个点,最上面的is_com_interface有两个模版参数,
第一个是T, 第二个是void, void没什么意义,主要用来做特化匹配.
下面是重点,typename T只有一个参数,默认外部调用的都是这个模板,例如COMPtr<ITaskService>
std::void_t<条件...> 这个条件如果成立,就会变成void, 就能用上这个模版了
第一个条件:decltype(std::declval<T>().Release())
std::declvar<Type> 这个函数返回一个Type的对象, 用来模拟运行时的情况,然后可以模拟调用运行时的方法.
decltype是一个类型提取器,返回值就是一个Type,运行方式sizeof很像,只能在编译期运行,不能在运行时调用。
如果declval模拟的对象的Release方法调用失败了,那就没有返回值,decltype就会报错,就无法匹配到这个模版了。
第二个条件:std::enable_if_t<std::is_base_of_v<IUnknown, T>>
这个简单一些,判断T是否是IUnknown的子类,是就enable_if_t<true> 返回 void
不是就enable_if_t<false> 触发SFINAE,退回上面的模版。
写了C++才发现,Rust这个语言本身很多的原语设计都是沿袭了C++的设计。
生命周期,智能指针,这些概念C++本身也有,只是并不强迫你使用。Rust只是做的更加激进罢了。
也许是Win32编程的缘故,我遇到需要显式分配和释放内存的场景很少,如果有也能封装成RAII的方式来管理资源。
或许需要显式的手动分配和释放内存的时代早就结束了…
Loading...