当前位置: 首页 > news >正文

理解UE4中C++17的...符号及enable_if_t的用法及SFINAE思想

下面是一段C++17的代码:

//函数1:

template <typename... BufferTypes,
std::enable_if_t<std::conjunction<CanAppendBufferType<std::decay_t<BufferTypes>>...>::value> * = nullptr>
inline explicit FCompositeBuffer(BufferTypes&&... Buffers) 

if constexpr (sizeof...(Buffers) > 0)
{
Segments.Reserve((GetBufferCount(Forward<BufferTypes>(Buffers)) + ...));
(AppendBuffers(Forward<BufferTypes>(Buffers)), ...);
Segments.RemoveAll(&FSharedBuffer::IsNull);
}
}

红色字体表示语法上的整体。

1、 template <typename... BufferTypes, 表示声明若干个类型名;

2、CanAppendBufferType< std::decay_t<BufferTypes> > 这是一个关于类型的调用,具体含义先忽略;

3、std::conjunction<CanAppendBufferType<std::decay_t<BufferTypes>>...>

将它看成此形式: std::conjunction<  condition<BufferTypes>...  >

此时,红色字体是一个整体,... 将会unpack(解压)  condition<SomeArgs> 这个模式,并以逗号分割的参数形式,传递给 std::conjunction ,即等价于:

 std::conjunction<  condition<BT1>, condition<BT2>, condition<BT3>  >

4、std::conjunction< a, b, c >::value  的意思是 a || b || c 的值,但是,它是模板元编程,也就是在“编译时期”计算 a||b||c 的,不会影响运行时性能,且不能用 || 来代替,且a\b\c 都是编译时确定值的变量,而非类型。

5、std::enable_if_t< some_value >  其实是 std::enable_if_t< some_value , void > 的简称,且 std::enable_if_t 的定义是:

template <bool _Test, class _Ty = void>
using enable_if_t = typename enable_if<_Test, _Ty>::type;

enable_if<the_value, the_type> ::type 的 意思是 

如果the_value是true,则定义为形式2,如果the_value是false,则定义为形式1 。

template <bool _Test, class _Ty = void>
struct enable_if {}; // no member "type" when !_Test   //形式1template <class _Ty>
struct enable_if<true, _Ty> { // type is _Ty for _Test  //形式2using type = _Ty;
};

此时根据 C++17模板元编程的原则 “SFINAE(Substitution Failure Is Not An Error,替换失败并非错误)” ,如果找不到 ::type  ,那么就忽略掉模板函数,而非报错。

同时,enable_if_t 是 typename enable_if<_Test, _Ty>::type; 的昵称。因此 std::enable_if_t< some_value >  的意思是,如果有 some_value 的值,那么此处就以 void 来定义,如果没有,那么就当该函数 (函数1)不存在。

6、template <typename... BufferTypes,     some_type  * = nullptr>  

由于5的论述,我们知道,some_type 只可能是 void ,否则把该模板函数(函数1)当做不存在。那么上述表达等价于:

template <typename... BufferTypes,   void * = nullptr>

不妨补充其匿名的名称为 secretboy ,如下

template <typename... BufferTypes,   ( void * ) secretboy = nullptr>

也就是说,逗号的后面,是一个值(而不是类型),且该值没有名字,它不会被函数体用到,那么它无关紧要。既然无关紧要,为啥还需要它呢?因为要让它的计算起到 SFINAE 的作用。所以,如果5合法,那么 它等价于 

template <typename... BufferTypes >

如果5不合法,那么忽略函数1的存在。

7、  if constexpr (sizeof...(Buffers) > 0)

表示如果 Buffers 有真实的数量,那么 就需要编译下面的代码,否则不用编译。

8、(GetBufferCount(Forward<BufferTypes>(Buffers)) + ...) 

我们把它简化为这个形式: (func(BufferTypes) + ... )

其中的 + ,在语法上还可以是 -  (减号)  || (或者),甚至是 , (逗号) 。

也就是说,函数调用后的 参数包 ,可以展开,等价于:

func(BT1) + func(BT2) + ...    (式子8)

并且请注意,  args + ... 的展开等价于 a + ( b + ( c + d ) ) ,所以严格来说,式子8不够严谨,应该等价于:

func(BT1) + ( func(BT2) + ( ... ) )    (式子9)


文章转载自:

http://JruLyYL8.srbfz.cn
http://nzPJp6YK.srbfz.cn
http://PKsbJePP.srbfz.cn
http://G6MskdSM.srbfz.cn
http://ltHG5szJ.srbfz.cn
http://C4AtWPxw.srbfz.cn
http://o0oSnz7X.srbfz.cn
http://a5wqEiFV.srbfz.cn
http://WMEye0HN.srbfz.cn
http://78K2n8WG.srbfz.cn
http://s8Onespk.srbfz.cn
http://Y5clFbgX.srbfz.cn
http://0ulJ8TyO.srbfz.cn
http://Fm3pFLxQ.srbfz.cn
http://6SkLKEuE.srbfz.cn
http://xEF156Uo.srbfz.cn
http://eFH6U9yB.srbfz.cn
http://r1skYOD9.srbfz.cn
http://ndBRVMly.srbfz.cn
http://csapj9ZP.srbfz.cn
http://RwOZQlnf.srbfz.cn
http://LjXnL2Nn.srbfz.cn
http://YtzlOVY0.srbfz.cn
http://ecMLkBEY.srbfz.cn
http://0A7gHBRz.srbfz.cn
http://vItvA2sW.srbfz.cn
http://nVzpHd8d.srbfz.cn
http://nXtOqfC7.srbfz.cn
http://D2mHsR2S.srbfz.cn
http://fCAmJP9H.srbfz.cn
http://www.dtcms.com/a/368296.html

相关文章:

  • 某头部能源集团“数据治理”到“数智应用”跃迁案例剖析
  • 阿里云服务器配置ssl-docker nginx
  • 2025年COR SCI2区,基于近似细胞分解的能源高效无人机路径规划问题用于地质灾害监测,深度解析+性能实测
  • 实战案例:数字孪生+可视化大屏,如何高效管理智慧能源园区?
  • 容器的定义及工作原理
  • 【Python - 类库 - BeautifulSoup】(01)“BeautifulSoup“使用示例
  • 神经网络之深入理解偏置
  • 三、神经网络
  • 仓颉编程语言青少年基础教程:布尔类型、元组类型
  • UC Berkeley 开源大世界模型(LWM):多模态大模型领域世界模型技术新进展
  • 一次由CellStyle.hashCode值不一致引发的HashMap.get返回null问题排查
  • 【Java鱼皮】智能协同云图库项目梳理
  • 固定资产报废在BPM或OA中审批,再通过接口传到SAP
  • Redis-持久化
  • 寻找AI——初识3D建模AI
  • Playwright MCP Server - FAQ
  • Linux系统TCP/IP网络参数优化
  • 多模联邦查询网关:ABP + Trino/Presto 聚合跨源数据
  • 基于单片机智能家居环境检测系统/室内环境检测设计
  • 23种设计模式-模板方法模式
  • 容器学习day05_k8s(二)
  • ES04-批量写入
  • 大数据毕业设计推荐:基于Spark的零售时尚精品店销售数据分析系统【Hadoop+python+spark】
  • 企业数字安全双保险:终端安全与数据防泄漏如何构筑全方位防护体系
  • 信息系统安全保护措施文件方案
  • 【C++】 list 容器模拟实现解析
  • 鹿客发布旗舰新品AI智能锁V6 Max,打造AI家庭安全领域新标杆
  • 【GEOS-Chem 输入数据】使用 AWS CLI 访问 GEOS-Chem 数据
  • 23种设计模式——原型模式 (Prototype Pattern)详解
  • 《Cocos Creator的2D、3D渲染使用记录》