Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将变量模板限制为类型列表_C++_Templates_Gstreamer_Unique Ptr - Fatal编程技术网

C++ 将变量模板限制为类型列表

C++ 将变量模板限制为类型列表,c++,templates,gstreamer,unique-ptr,C++,Templates,Gstreamer,Unique Ptr,我正试图通过添加智能指针使一些代码现代化。例如: 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, GstElement

我正试图通过添加智能指针使一些代码现代化。例如:

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");
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\u object\u unref
解除分配的类型。是否有一种方法可以声明模板仅与类型列表一起工作-
GstElement
GstBus
等?

也许您可以将模板设置为
操作符()
(因此无需显式定义智能指针的模板参数),并使用SFINAE启用
操作符()
仅适用于允许的类型

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); }
 };
也许是一种性格特征?看看你以前是否见过这些

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;
模板
结构can\u gst\u unref:std::false\u type{};
//对于每种类型。。。
模板结构can\u gst\u unref:std::true\u type{};
//方便的别名,这是类型特征的惯例
模板
内联constexpr bool can\u gst\u unref\u v=can\u gst\u unref::value;
//现在,在删除程序中有条件地定义运算符()
结构GstDeleter{
模板
std::enable_if_t operator()(t*p){gst_object_unref(p);}
};
//使函数成为模板而不是类可以减少使用时的混乱
标准:独特的ptr工程(gst管道新(“测试管道”);
//can\U gst\U unref不是专用于std::string的
//因此,一般情况下,给出can\u gst\u unref\u v=false
//std::如果\u t因此不生成类型,则启用\u,并且未定义运算符(),因为它没有返回类型
//因此,这不会编译
性病:独特的呼;

您可以使用std::enable_,如果子集不应该只是
GstObject*
,那么
struct GPointerDeleter{void operator()(GstObject*p)const{gst\u object_unref(p);}
?@Jarod42您可能会认为,但是不-它们实际上没有定义为GstObject,它们的结构中有一个指向GstObject的指针。如果问题标记为C++17,则可以用
std::enable\u和
std::is_same\u v
@churill缩短。但问题只标注了C++。我们知道OP至少使用了C++11(使用
std::unique\u ptr
),当然,我只使用与C++11兼容的代码。
static\u assert
在这里似乎比SFINAE更合适。@Jarod42-你的意思是“没有其他选择,所以软错误会给出与硬错误相同的结果”吗?嗯。。。也许你是对的…@Jarod42-是的:是有意的;还可以简化智能指针声明。我试着解释,但也许我的英语错了。
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;