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

UE4 Mac构建编译报错 no member named “disjunction” in namespace “std”

背景

我的工程在编译iOS时,遇到如下报错:

2025-09-05 11:43:51:940 : /Users/bkdevops/_ios1/EngineSource/Engine/Source/Runtime/Core/Public/Containers/Array.h:46:53: error: no member named 'disjunction' in namespace 'std'
 

分析

由于WINDOWS的构包没有这个报错,因此先观察其(disjunction)定义。WINDOWS下定义在 C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.40.33807\include\xtr1common ,如代码1,Mac下的定义在  

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/__type_traits/disjunction.h ,如代码2。

//代码1:
_EXPORT_STD template <class... _Traits>
struct disjunction : false_type {}; // If _Traits is empty, false_typetemplate <class _First, class... _Rest>
struct disjunction<_First, _Rest...> : _Disjunction<_First::value, _First, _Rest...>::type {// the first true trait in _Traits, or the last trait if none are true
};
//代码2:
// _Or always performs lazy evaluation of its arguments.
//
// However, `_Or<_Pred...>` itself will evaluate its result immediately (without having to
// be instantiated) since it is an alias, unlike `disjunction<_Pred...>`, which is a struct.
// If you want to defer the evaluation of `_Or<_Pred...>` itself, use `_Lazy<_Or, _Pred...>`
// or `disjunction<_Pred...>` directly.
template <class... _Args>
using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>;#if _LIBCPP_STD_VER >= 17template <class... _Args>
struct disjunction : _Or<_Args...> {};template <class... _Args>
inline constexpr bool disjunction_v = _Or<_Args...>::value;#endif // _LIBCPP_STD_VER >= 17

由于我的Mac构建机没有配置为 _LIBCPP_STD_VER  17 ,具体原因见我的下一篇博文(UE4 Mac构建编译报错 no template named “is_void_v” in namespace “std”-CSDN博客)。因此 disjunction 未定义。

最终方案

在UE4的使用了disjunction 的地方,改为下面形式:

#if PLATFORM_IOS
constexpr bool TArrayElementsAreCompatible_V = std::_Or<std::is_same<DestType, std::decay_t<SourceType>>, std::is_constructible<DestType, SourceType>>::value;
#else
constexpr bool TArrayElementsAreCompatible_V = std::disjunction<std::is_same<DestType, std::decay_t<SourceType>>, std::is_constructible<DestType, SourceType>>::value;
#endif

disjunction的含义

针对代码2,下面这个表格汇总了代码中关键部分及其含义:

代码片段

含义

#if _LIBCPP_STD_VER >= 17

条件编译预处理指令​:检查 libc++ 的配置宏 _LIBCPP_STD_VER是否表示支持 C++17 或更高版本。

_LIBCPP_STD_VER

libc++ 内部宏​:其整数值代表 libc++ ​目标遵循的 C++ 标准版本,例如 17代表 C++17,20代表 C++20。

template <class... _Args> struct disjunction : _Or<_Args...> {};

std::disjunction的主模板定义​:它继承自一个内部实现 _Or

std::disjunction

C++17 标准引入的模板​:对多个类型特性 (type traits)​​ 进行逻辑或 (OR) 运算的元函数。

template <class... _Args> inline constexpr bool disjunction_v = _Or<_Args...>::value;

C++17 标准引入的变量模板​:是 disjunction<_Args...>::value的简写,方便使用。

#endif

结束条件编译块。

🔧 ​std::disjunction的功能与原理

std::disjunction是一个模板元函数,它接受任意数量(变长模板参数 class... _Args)的类型特性(例如 std::is_integral<T>, std::is_floating_point<T>等),并计算它们的逻辑或。

  • 运算规则​:相当于 T1::value || T2::value || ... || Tn::value,但是在编译期进行的。

  • 短路求值​:这是 disjunction一个非常重要的特性。如果在模板参数包 _Args...中,​某个类型特性 Bivalue静态成员为 true,那么 disjunctionvalue就是 true,并且编译器会停止实例化后续的类型特性​(即不会去计算 Bj::value,其中 j > i)。这在后续的类型实例化代价高昂或可能导致编译错误时特别有用。

  • 继承关系​:std::disjunction<B1, B2, ..., BN>会公开继承自第一个 valuetrueBi类型。如果所有 Bi::value都为 false,则继承自最后一个 BN。这意味着你不仅可以获取最终的 ::value,有时还可以获取到符合条件的那个特性类型本身的信息。

💡 ​简单示例

#include <type_traits>
#include <iostream>int main() {// 检查类型 T 是否是整型或浮点型之一using T = double;if (std::disjunction_v<std::is_integral<T>, std::is_floating_point<T>>) {std::cout << "T is either integral or floating point.\n";} else {std::cout << "T is neither integral nor floating point.\n";}return 0;
}

在这个例子中,std::disjunction_v<>会在编译期计算 std::is_integral<double>::value || std::is_floating_point<double>::value。由于 double是浮点类型,第二个特性的 valuetrue,因此整个 disjunction_v的结果为 true


文章转载自:

http://sy2GFfQ1.rmppf.cn
http://ASFt4gfn.rmppf.cn
http://PCiWCJUo.rmppf.cn
http://MCgDUIIM.rmppf.cn
http://3EpCF7R0.rmppf.cn
http://o9OKjU4G.rmppf.cn
http://4a3W7TuP.rmppf.cn
http://C6aple9j.rmppf.cn
http://bBaFy0SV.rmppf.cn
http://qbu9zTUZ.rmppf.cn
http://vXbJWkxL.rmppf.cn
http://mBBdt43I.rmppf.cn
http://oKI1jwtG.rmppf.cn
http://9ExJA1f0.rmppf.cn
http://5N737ciz.rmppf.cn
http://qUejG9Mx.rmppf.cn
http://BlyovbXh.rmppf.cn
http://Dgoly8o5.rmppf.cn
http://vdJ7UlLO.rmppf.cn
http://BCMxtigD.rmppf.cn
http://a7TjLT9c.rmppf.cn
http://Z4nCGtKM.rmppf.cn
http://fzrJyLIr.rmppf.cn
http://EuLREZHr.rmppf.cn
http://YaWFxoEO.rmppf.cn
http://7hYNYuJF.rmppf.cn
http://Ps4cSCpa.rmppf.cn
http://yVHvJRVo.rmppf.cn
http://idHh6094.rmppf.cn
http://jb3N5mW7.rmppf.cn
http://www.dtcms.com/a/368675.html

相关文章:

  • 深度相机详解
  • vue 经常写的echarts图表模块结构抽取
  • 蚂蚁 S21e XP Hyd 3U 860T矿机性能分析与技术特点
  • Python迭代协议完全指南:从基础到高并发系统实现
  • CT影像寻找皮肤轮廓预处理
  • 7种流行Prompt设计模式详解:适用场景与最佳实践
  • uni-app 项目 iOS 上架踩坑经验总结 从证书到审核的避坑指南
  • 3.3_第一行之hard_local_irq_disable
  • 汽车 信息娱乐系统 概览
  • 将已有 Vue 项目通过 Electron 打包为桌面客户端的完整步骤
  • Nginx 配置片段主要用于实现​​正向代理​​,可以用来转发 HTTP 和 HTTPS 请求
  • 有鹿机器人的365天奇幻日记:我在景区当扫地僧
  • C++算法专题学习——分治
  • 智能工单路由系统(Java)
  • 生成模型实战 | 深度分层变分自编码器(Nouveau VAE,NVAE)
  • Windows多开文件夹太乱?Q-Dir四窗口同屏,拖拽文件快一倍
  • 测试驱动开发 (TDD) 与 Claude Code 的协作实践详解
  • Bug 排查日记:打造高效问题定位与解决的技术秘籍
  • MySQL InnoDB索引机制
  • Nextcloud 实战:打造属于你的私有云与在线协作平台
  • linux上nexus安装教程
  • vosk语音识别实战
  • 美团发布 | LongCat-Flash最全解读,硬刚GPT-4.1、Kimi!
  • 七彩喜微高压氧舱:科技与体验的双重革新,重新定义家用氧疗新标杆
  • Gemini-2.5-Flash-Image-Preview 与 GPT-4o 图像生成能力技术差异解析​
  • 敏捷开发-Scrum(上)
  • 超越自动化:为什么说供应链的终局是“AI + 人类专家”的混合智能?
  • 一维水动力模型有限体积法(三):戈杜诺夫框架与近似黎曼求解器大全
  • 2025年互联网行业高含金量证书盘点!
  • 数据库存储大量的json文件怎么样高效的读取和分页,利用文件缓存办法不占用内存