将变量模板限制为类型列表
Limit variable template to a list of types
我正试图通过添加智能指针来使一些GStreamer代码现代化。例如:
GstElement *pipeline = gst_pipeline_new("test-pipeline");
gst_object_unref(pipeline);
可以重写:
struct GstElementDeleter {
void operator()(GstElement* p) { gst_object_unref(p); }
};
std::unique_ptr<GstElement, GstElementDeleter> pipeline = gst_pipeline_new("test-pipeline");
但gst_object_unref()
可以在任何gpointer
上使用,因此可以重写:
template<typename T>
struct GPointerDeleter {
void operator()(T* p) { gst_object_unref(p); }
};
std::unique_ptr<GstElement, GPointerDeleter<GstElement>> pipeline = gst_pipeline_new("test-pipeline");
但我想做的是将其限制为仅处理可以使用gst_object_unref
解除分配的类型。有没有一种方法可以声明模板只适用于类型列表GstElement
、GstBus
等?
也许您可以将模板设为operator()
(因此无需显式定义智能指针的模板参数(,并使用SFINAE仅为允许的类型启用operator()
struct GPointerDeleter
{
template <typename T>
typename std::enable_if<std::is_same<T, GstElement>::value
|| std::is_same<T, GstBus>::value
/* or other cases */
>::type operator() (T * p) const
{ gst_object_unref(p); }
};
或者,也许更好的是,您可以在operator()
中添加(如Jarod42(谢谢(所建议的(static_assert()
检查
struct GPointerDeleter
{
template <typename T>
void operator() (T * p) const
{
static_assert( std::is_same<T, GstElement>::value
|| std::is_same<T, GstBus>::value
/* or other cases */, "some error message" );
gst_object_unref(p);
}
};
也许是类型特征?如果您以前没有见过这些内容,请参阅<type_traits>
。
template<typename T>
struct can_gst_unref : std::false_type { };
// for each type...
template<> struct can_gst_unref<GstElement> : std::true_type { };
// convenient alias, as is convention for type traits
template<typename T>
inline constexpr bool can_gst_unref_v = can_gst_unref<T>::value;
// now conditionally define operator() in your deleter
struct GstDeleter {
template<typename T>
std::enable_if_t<can_gst_unref_v<T>> operator()(T* p) { gst_object_unref(p); }
};
// Making the function a template instead of the class reduces clutter at usage
std::unique_ptr<GstElement, GstDeleter> works(gst_pipeline_new("test-pipeline"));
// can_gst_unref is not specialized to std::string
// so the general case takes over, and gives can_gst_unref_v<std::string> = false
// std::enable_if_t thus doesn't produce a type, and operator() is not defined, because it has no return type
// therefore, this doesn't compile
std::unique_ptr<std::string, GstDeleter> whoops;
相关文章:
- 使用简单类型列表实现的指数编译时间.为什么
- 从类型列表中递归删除重复项会导致编译器堆空间错误 (VS2017)
- 测试两个类型列表中的所有组合
- 谷歌测试:模板模板的笛卡尔乘积的类型列表与模板
- 在迭代模板类型列表时无法停止递归
- 将可变参数类型列表的扩展打包为复杂类型的初始值设定项列表 - 合法吗?
- 阅读从 istream 到矢量的不同类型列表
- 如何在C++中创建类型列表的 n 路笛卡尔积?
- c++17通过生成预先声明的类型列表的笛卡尔乘积来生成std::变体
- 将变量模板限制为类型列表
- 我可以使用特征指定变体的类型列表吗?
- 如何对要用于模板参数的类型列表进行编码
- 创建类型列表并访问每种类型的静态成员?
- 为什么BOOST :: HANA :: EXAREMIS ::键入实验功能?类型列表的棘手是什么
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- std::仅移动类型列表:不能在 VC++ 中放入 std::vector
- C++类型列表创建子列表
- 调用STD ::功能,并带有变体类型列表
- 在没有宏的情况下在 C++98 中创建类型列表时遇到问题
- 如何从类型列表重建参数包