首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++那些事之SFINAE

您所见,序列化过程,很容易检查对象是否具有属性并查询该属性类型我们例子,它允许我们使用serialize方法(如果可用),否则返回到更通用方法str。功能强大,不是吗?...您可以使用解决方案变体对类型进行大量测试(测试成员,子类型...),我建议您更多地搜索SFINAE技巧。...我带给您难题最后一部分,称为enable_if您所见,我们可以使用enable if根据编译表达式触发替换失败。...c++ 11,constexpr有很多规则,只能使用一小部VIEs(非常重要表达式)表达式(没有循环……)!...decltype,将评估所有表达式,但仅将最后一个表达式视为该类型。序列化不需要任何更改,减去了STL现在提供了enable_if函数事实。

2.1K20

现代C++之SFINAE

您所见,序列化过程,很容易检查对象是否具有属性并查询该属性类型我们例子,它允许我们使用serialize方法(如果可用),否则返回到更通用方法str。功能强大,不是吗?...您可以使用解决方案变体对类型进行大量测试(测试成员,子类型...),我建议您更多地搜索SFINAE技巧。...我带给您难题最后一部分,称为enable_if您所见,我们可以使用enable if根据编译表达式触发替换失败。...c++ 11,constexpr有很多规则,只能使用一小部VIEs(非常重要表达式)表达式(没有循环……)!...decltype,将评估所有表达式,但仅将最后一个表达式视为该类型。序列化不需要任何更改,减去了STL现在提供了enable_if函数事实。

2.9K20
您找到你想要的搜索结果了吗?
是的
没有找到

【C++11】消除重复, 提升代码质量---type_tratis

: false D: true 1.4 获取可调用对象返回类型traits std::result_of可以在编译器获取可调对象返回类型,帮助解决编码过程如下问题: 函数入参为模板参数,不能直接确定函数返回类型...; 通过decltype推导函数返回类型可读性差问题; 使用后置推导类型,如果没有构造函数导致编译报错问题; std::result_of原型如下: template <class Fn, class...main() { Fun(1); return 0; } 程序运行为最终会匹配到第二个模板函数,但是实际匹配过程,当匹配到void Fun(T*)用整数对T*进行替换是错误,但是编译器会继续匹配...,直到匹配到void Fun(T)后执行正确函数,这种规则就是SFINAE;反之,如果一个模板函数都没有匹配到,则编译器会报如下错误: error: no matching function for...使用std::enable_if可以实现一个强大重载机制,充分利用可以减少或者消除圈复杂度。:根据不同数据基本类型转换为string进行输出。

1.6K10

C++11:unique_ptr 自己定义类似make_sharedmake_unique模板函数

C++11智能指针分为共享型shared_ptr和独占型unique_ptr,C++11提供了make_shared函数来创建shared_ptr指针,使用起来更方便,有了make_shared...用到了名为std::enable_iftype_traits,它类似一个if语句,判断ZERO,当ZERO为true编译器选择第一个版本函数,反之选择第二个。...enable_if是C++11头文件一个类,关于enable_if用法详细说明参见: class template std::enable_if...其实我是写完上面的代码VS2015下编译,报了个错, 我这才发现,VS2015已经提供了make_unique 以下是来自VS2015头文件make_unique...实现代码,代码创建普通对象和数组对象函数名都是make_unique,与我写版本不一样,而且微软版本没有区分是否初始化数组,一律初始化为0。

1.1K20

性能优化利器之constexpr

从概念上理解的话,constexpr即常量表达式,重点在表达式字段,用于指定变量或函数可以常量表达式中使用,可以(或者说一定)在编译求值表达式,而const则为了约束变量访问控制,表示运行时不可以直接被修改...自C++17起,引入了if constexpr语句,本节,将借助SFINAE 和 std::enable_if来实现一个简单Square功能,最后借助if constexpr对代码进行优化(如果对...为了解决这个问题,我们尝试引入std::enable_if操作,如下: template typename std::enable_if<std::is_arithmetic<T...,如果是算术类型,则调用第一个,否则调用第二个,完整代码如下: #include template typename std::enable_if<...我们借助一个Square()函数模板以及更加符合编码习惯if语句就能解决上面的问题,且比使用std::enable_if方式更为优雅和符合阅读习惯,进而提高代码可阅读性。

29310

std::shared_ptr 线程安全性 & 多线程使用注意事项

我们讨论 std::shared_ptr 线程安全,讨论是什么? 讨论之前,我们先理清楚这样一个简单但却容易混淆逻辑。...std::shared_ptr 是个类模版,无法孤立存在,因此实际使用,我们都是使用具体模版类。...这里使用 std::shared_ptr 来举例,我们讨论时候,其实上是讨论 std::shared_ptr 线程安全性,并不是 SomeType 线程安全性。...() 函数是否线程安全,这里显示是非线程安全,因为对 some_value 操作没有加锁,也没有使用 atomic 类型,多线程访问就出现未定义行为(UB) std::shared_ptr 线程安全性...ThreadSanitizer: reported 4 warnings Terminated due to signal: ABORT TRAP (6) 从错误信息可以清晰地看到出现数据竞争,

2.1K10

能向入口函数传入多个参数 QueueUserWorkItem

std::tuple; using std::mem_fn; using std::result_of; using std::enable_if; using std::true_type; using..._Func 绑定到之上对象指针,参见 示例1.2; 4、QueueUserWorkItemEx 完成参数拷贝后返回,而非向线程池任务队列投递任务后立即返回;原因是 若在目标线程拷贝参数前返回可能导致目标线程使用已被销毁对象...这可能会导致线程池依托任务队列建立可 伸缩性失效,具体解决方法请参考注意事项第1条。 注意: 1、当Args参数包参数数量不为零会引起等待;等待线程池中线程调用_Func 前参数拷贝完成。...建议解决方法是使用参数数量为零lambda,并捕获所需参数,让拷贝提前发生。 2、若用户试图嵌套调用 QueueUserWorkItemEx ,将得到一个“IO未决”错误。...5、参数包包含某些对象初始化过程可能会创建某些依赖于线程内部对象( Windows 窗口对象), 对于此情况,我建议是不要作为参数传递,或改用 std::async 。

1.2K20

实际工程 C++ 模板

这里 lib::void_t 是什么?std::void_t 是 C++ 17 之后才 STL 中提供模板,它很简单也非常有用,功能是将任意类型序列映射到 void 上,也就是忽略掉这些类型。...>::type; 这里使用 void_t 将多个类型声明忽略掉以适应 template 第二个类型参数: decltype(std::begin...所以我们只能使用 adapter 模式解决这个问题: struct MyDataBlobAdapter { using key_type = ...; void SetKey(key_type...这个 IsLegalDb 实现也用到了 SFINAE,大致可以实现为这样: template struct IsLegalDb: std::false_type...第一是我们这里类型 3 和 5 处继承了 std::true_typestd::false_type,这两个类型可以认为是类型级别的 true 和 false头文件 <type_traits

2K20

C++11 元编程(meta-programming)判断T是否有==操作符

基本原理与文中差不多,利用SFINAE原则,通过返回类型后置来推断表达式类型,推断过程利用declval,它可以获取类型右值引用,以便来调用==操作符,这个过程是在编译期完成。...test(...)函数,它返回类型void。...test(...); enum{value=std::is_same(0)), bool>::value}; }; 在上面代码,推导test(int)返回类型表达式是由执行...对于基本数据类型(比如int),因为没有成员函数,所以第二种方式对于基本类型返回肯定是false.无法用这种方式判断基本数据类型是否有==操作符,只适用于class类型。...下面是完整代码 #include #include using namespace std; struct test_classA{ int

28230

opencl:cl::make_kernel进化

调用都要有上面两个动作,概括起来就是 执行kernel之前,如果kernel参数中有指针类型或imag类型参数,需要将参数主机端对应cl::Memory类型(其子类包括cl::Image,cl:...所有变长参数类型进行识别, * 对于memory_cl类型参数,根据需要在kernel执行前上传数据到设备, * 并在kernel执行后根据需要下载输出数据到主机 * 模板N参数,用于调试知道哪个参数出错...* * */ // 参数ARG为非memory_cl类型直接返回,啥也不做 template typename std::enable_if<!...,const ARG & arg){} // 参数ARG是memory_cl类型,根据需要上传数据 template typename std::enable_if...;//递归处理其他参数 } // 参数ARG为非memory_cl类型,为空函数,啥也不做直接返回 template typename std::enable_if

1.4K20

C++ enable_shared_from_this 具体实现

C++ 中使用 std::shared_ptr 智能指针不当有可能会造成循环引用,因为 std::shared_ptr 内部是基于引用计数来实现, 当引用计数为 0 ,就会释放内部持有的裸指针。...但是当 a 持有 b, b 也持有 a ,相当于 a 和 b 引用计数都至少为 1,因此得不到释放,RAII 此时也无能为力。这时就需要使用 weak_ptr 来打破循环引用。...可以看到,构造 DataFetch 时候, 我们使用了 shared_from_this() 作为参数: data_fetcher_ = std::make_shared(..._NOEXCEPT {} 对于第一个问题,就是 enable_if作用: enable_if::type 意思是说,如果bool值为true,enable_if 返回就是第二个模版参数...类型T, 如果为false,返回空(不是void,而是什么也没有) 那么看下: enable_if<is_convertible<_OrigPtr*, const enable_shared_from_this

90330

Chapter 5: Rvalue References, Move Semantics, PF

,再重新转发到标签分发函数,再次分发 logAndAdd(nameFromIdx(idx)); } 上面的std::true_typestd::false_type就是标签,我们可以利用它们来强制选择我们希望调用重载函数...对于用户自定义类型而言,他们是继承自自身,也就是说std::is_base_of会返回为true,但是当T是内建类型,就会返回为false。...没有显式支持移动操作或不满足编译器自动生成移动操作类型 并非所有支持移动标准库容器都会受益于移动操作 对于把内容存储堆内存,而自身只保存指向该堆内存指针容器类型来说,移动操作仅仅是拷贝这个指针到新容器...这种情况下出错类型有: 编译器无法推导出一个类型:只要参数中有一个及以上无法推导出类型,就无法编译 编译器推到出错误类型:要么是推导出来类型使得无法编译,要么是推到出来类型重载函数情况下匹配到错误函数调用...同样,将MinVals传递到模板函数fwd,这个模板参数是一个引用,它本质上和指针是一样,只不过是一个会自动解引用指针,那么在编译该函数就需要对MinVals进行取地址,而MinVals此时并没有定义

5.1K40

C++11 JNI开发RAII应用(一)--制作基础工具

第二个场景以jni代码(native code)创建java 对象数组为例说明,jni代码创建大量本地引用而不显式释放可能会导致out of memory。...反正我不想在写代码总掂记着引用有没有释放问题。...struct返回resource地址 //这里->操作符使用了函数模板实现,用到了is_pointer和is_class两个type_trait来判断T类型, //如果T不是指针,也不是class.../struct,则没有->操作符实现 同样为了方便调用,还增加了支持类型转换模板函数_get(),允许指定返回类型调用_get(),比如 raii_obj...._get(),调用_get()将raii_obj对象转成jstring类型 /* 根据 _T类型不同选择不同函数模板 */ template<typename

35810

灵魂拷问std::enable_shared_from_this,揭秘实现原理

灵魂拷问std::enable_shared_from_this,揭秘实现原理 引言 C++编程使用智能指针是一种安全管理对象生命周期方式。...为了解决这个问题,C++引入了std::enable_shared_from_this类,本文将深入探讨其基础知识、使用案例以及内部实现。...多个 shared_ptr 实例通过共享 控制块 结构来控制对象生命周期。 当使用原始指针构造或初始化 shared_ptr ,会创建一个新控制块。...可能情况下,尽量使用 std::make_shared(或 std::allocate_shared)来减少发生错误可能性。...但首先,像下面这样尝试使用 this 指针创建 shared_ptr 不会起作用,原因如上所述: struct Foo { std::shared_ptr getSelfPtr() {

42810
领券