「这是我参与11月更文挑战的第 1 天,活动详情查看:2021最后一次更文挑战」。
接上一篇C++ 中的可变参数函数模板 其实不仅可以定义可变参的函数模板,可变参模板类也是可以定义的。
定义:可变参模板类是一个带可变模板参数的模板类
最近在学习 AE 的插件开发,里面有些例子也涉及到了可变参类模板,所以以下代码参考自 AE 的插件开发源码。
首先是(两段式的,即无前向声明)变参模板定义的结构体
/// @note 可变参模板定义结构体【基本定义】
template <typename ReturnType, typename... Arguments>
struct CallbackType
{
/// @note 类型取别名 type: 原类型 function 封装 “可调用对象” 依赖模板提供的返回值和参数类型
using type = std::function<void(ReturnType, Arguments...)>;
};
/// @note 偏特化可变参类型,无返回值【递归终止条件】
/// https://www.cnblogs.com/qicosmos/p/4325949.html
template <typename... Arguments>
struct CallbackType<void, Arguments...>
{
using type = std::function<void(Arguments...)>;
};
接着,使用到以上二者的可变参模板类 Function 的定义代码如下, 说明详见代码注释
/// @note 可变参的模板定义类
template <typename ReturnType, typename... Arguments>
class Function : public AbstractFunction
{
friend struct FunctionHelper<ReturnType, Arguments...>;
using Signature = ReturnType(WINAPI *) (Arguments...); ///< 类型重定义:函数指针类型(签名)
/// @note 对 (返回值为 void 的) CallbackType 中 type 类型取别名 BeforeCallback
/// 这里 typename 的作用是标明 “嵌套依赖类型名”
/// 因为它是个类型而不是变量,而且依赖模板提供的(可变)参数
using BeforeCallback = typename CallbackType<void, Arguments...>::type;
/// @note 同上,只不过有指定返回值类型 ReturnType
using AfterCallback = typename CallbackType<ReturnType, Arguments...>::type;
public:
Function(const char * name);
/// @note 可变参成员函数
ReturnType operator()(Arguments&... arguments) const;
ReturnType directCall(Arguments... arguments) const;
/// @note 传入变量类型正是上面自定义的类型,本质上是个封装了 “可调用对象” 的 std::function 对象
void setBeforeCallback(BeforeCallback callback);
void clearBeforeCallback();
void setAfterCallback(AfterCallback callback);
void clearAfterCallback();
protected:
BeforeCallback m_beforeCallback;
AfterCallback m_afterCallback;
};
Function 类的具体实现代码如下,简化了一些比较复杂的干扰代码
template <typename ReturnType, typename... Arguments>
Function<ReturnType, Arguments...>::Function(const char * _name)
: AbstractFunction{_name}
, m_beforeCallback{nullptr}
, m_afterCallback{nullptr}
{
}
template <typename ReturnType, typename... Arguments>
ReturnType Function<ReturnType, Arguments...>::operator()(Arguments&... arguments) const
{
/// FunctionHelper 类的定义略(是分为有返回值【泛化】和无返回值【偏特化】的可变参模板类)
auto myAddress = address();
if (myAddress != nullptr)
{
if (isAnyEnabled(CallbackMask::Before | CallbackMask::After | CallbackMask::Logging))
{
/// @note 可变参数的传递方式,涉及了右值引用和完美转发
/// 内部会根据情况调用我们先前封装的 可调用实体
return FunctionHelper<ReturnType, Arguments...>().call(this, std::forward<Arguments>(arguments)...);
}
else
{
/// @note 同上
return FunctionHelper<ReturnType, Arguments...>().basicCall(this, std::forward<Arguments>(arguments)...);
}
}
else
{
if (isEnabled(CallbackMask::Unresolved))
{
unresolved();
}
return ReturnType();
}
}
template <typename ReturnType, typename... Arguments>
ReturnType Function<ReturnType, Arguments...>::directCall(Arguments... arguments) const
{
///< FunctionHelper 定义略,同上
return FunctionHelper<ReturnType, Arguments...>().basicCall(this, std::forward<Arguments>(arguments)...);
}
template <typename ReturnType, typename... Arguments>
void Function<ReturnType, Arguments...>::setBeforeCallback(BeforeCallback callback)
{
m_beforeCallback = std::move(callback);
}
template <typename ReturnType, typename... Arguments>
void Function<ReturnType, Arguments...>::clearBeforeCallback()
{
m_beforeCallback = nullptr;
}
template <typename ReturnType, typename... Arguments>
void Function<ReturnType, Arguments...>::setAfterCallback(AfterCallback callback)
{
m_afterCallback = std::move(callback);
}
template <typename ReturnType, typename... Arguments>
void Function<ReturnType, Arguments...>::clearAfterCallback()
{
m_afterCallback = nullptr;
}