MPL11 技术文档
1. 安装指南
MPL11 是一个头文件库。要在您的项目中使用它,只需将 include 目录添加到编译器的头文件搜索路径中即可。
该库没有依赖项,甚至不依赖标准库。但是,它需要一个支持 C++14 的编译器。测试套件在以下编译器中通过:
- clang 版本 3.4
- clang 版本 3.5.0
- GCC 4.9.0 20140302 (实验性)
- Apple LLVM 版本 5.1 (clang-503.0.38)
要编译单元测试,您还需要安装 [CMake]。安装完成后,您可以进入项目根目录并执行以下命令:
$ mkdir build
$ cd build
$ cmake ..
$ make tests # 编译单元测试。
精简版本
MPL11 也提供了一个精简版本。要使用它,只需包含 boost/mpl11.min.hpp 头文件,其中包含整个库。请注意,精简头文件不得与其他库头文件一起使用。
2. 项目使用说明
MPL11 是一个基于 C++11 的库,提供用于解决复杂模板元编程问题的可组合、高级基元。该库围绕几个核心概念构建;本教程的目的是介绍这些概念,而库提供的工具则留给了 参考文档。
本教程假设您对模板元编程和基本函数编程概念有很好的理解。此外,了解 Boost.MPL 库也将有所帮助。但是,MPL11 在很多方面都与 Boost.MPL 有所不同,因此在将知识从一个库转移到另一个库时,需要检查文档。
3. 项目 API 使用文档
以下是 MPL11 库的一些关键概念和使用的简要说明。
Metafunctions
非正式地,元函数是一个模板,表示一个编译时函数,它接受类型作为参数并返回一个类型作为结果。来自 MPL 的读者应该注意,这里的正式定义与 MPL 的定义不同。
正式地,设 f 为一个具有任意数量类型模板参数的 C++ 模板,且仅具有类型模板参数。如果存在类型 x1, ..., xn 使得 f<x1, ..., xn>::type 是一个有效的类型名,则 f 是一个 元函数。在这种情况下:
x1, ..., xn是f的 参数。- 形成特化
f<x1, ..., xn>被称为 暂停f与x1, ..., xn。 - 特化
f<x1, ..., xn>被称为 thunk 或 suspension。 - Thunk 的嵌套
::type被称为 thunk 的 结果。如果 thunk 的形式为f<x1, ..., xn>,我们也可以说它是f与x1, ..., xn的结果。 - 获取 thunk 的结果称为 评估 thunk。如果 thunk 的形式为
f<x1, ..., xn>,我们也可以说 调用f与x1, ..., xn或 应用f到x1, ..., xn。 - 元函数的 arity 是它可以被调用的参数数量。具有 n 个参数的元函数被称为 n-ary 元函数。
- 一个可以接受任意数量参数的元函数被称为 可变参数。根据定义,可变参数元函数对于任何非负整数 n 都是 n-ary。
重要的是要注意这个定义与 Boost.MPL 给出的定义之间的区别。根据这个定义,元函数永远不能是普通的 C++ 类型;它必须始终是模板。因此,Boost.MPL 实现为非模板类的零元元函数不被视为元函数。
以下是一些示例:
// 一个一元元函数。
template <typename x>
struct unary { struct type; };
// 一个二元元函数。
template <typename x, typename y>
struct binary { struct type; };
// 一个可变参数元函数。
template <typename ...>
struct variadic { struct type; };
// 一个零元元函数。它只能被调用 0 个参数,因此它是 0-ary(零元)。
template <typename ...> struct nullary;
template <> struct nullary<> { struct type; };
// 不是 MPL11 的元函数;它不是模板!
struct MPL_nullary { struct type; };
// 不是元函数;它从不具有结果(一个嵌套的 ::type)!
template <typename ...>
struct no_result { };
Boxed Types
非正式地,boxed 类型是一个尚未被评估的类型。因此,在知道boxed类型的实际“值”之前,必须评估它,这个过程称为解包。
正式地,对于任意的 C++ 类型 T,一个 boxed T 是一个任意的 C++ 类型 B,使得 B::type 是 T。在这种情况下,B 被称为 box(of T)和解包 T 的过程称为 unboxing T。
struct T;
struct B { using type = T; }; // 一个boxed T(等价于T的box)
B::type; // 解包T
相反,将任意类型 T 包裹在类型 B 中,使得 B::type 是 T 被称为 boxing T(到 B 或用 B)。重要的是要注意 B 可能依赖于 T,没有这一点,boxed 将失去其意义。
struct T;
template <typename t>
struct B { using type = t; };
B<T>; // 将T boxing到B
请注意,类型可以被boxed任意次。这可能不是很有用,但定义足够通用以允许它。
B<B<T>>; // 这是一个“B<T>的box”,即“T的box的box”
存在一个特殊的boxed类型名为 undefined(有时称为_bottom_),其特点是当它被解包时,即使在 SFINAE-able 上下文中也会导致编译时错误。undefined 可以被视为无效值或失败的计算结果。
以下是一些示例来说明前面的定义:
// 这个模板接受一个任意类型T并boxed它。
template <typename T>
struct box {
using type = T;
};
// 这些不是boxed。
class x;
struct y { char foo; };
char;
box<char>::type;
// 这些是boxed类型。
box<char>; // 一个boxed `char`
box<box<char>>; // 一个boxed `box<char>`
box<box<char>>::type; // 一个boxed `char`
struct x { using type = char; }; // 一个boxed `char`
struct y { struct type; }; // 一个boxed `y::type`
struct z { using type = z; }; // 自引用?为什么不!
重要的是要注意,boxed T 有很多不同的表示。这使得boxed类型之间的等价关系变得有点复杂。考虑以下内容:
struct T;
struct B1 { using type = T; }; // 一个boxed T
struct B2 { using type = T; }; // 另一个boxed T
当然,B1 和 B2 在他们boxed的类型上是等价的,因为他们都boxed了同一个类型 T。但是,B1 和 B2 在 C++ 类型系统上是不等价的,因为他们是不同的类型。现在,这很重要,因为它告诉我们不能使用模式匹配来定义一个接受boxed类型作为参数的元函数。确实,由于boxed类型的表示不是唯一的,我们无法预知我们的参数将具有什么形式,因此无法进行模式匹配。考虑以下内容:
// B 应该是一个boxed类型。
template <typename B>
struct f;
// 这应该处理boxed chars,但我们不知道boxed char可能看起来像什么!
template <>
struct f<????> {
// ...
};
现在,我们可能会尝试这样做:
// box 是我们之前定义的模板。它接受一个任意类型并boxed它。
template <>
struct f<box<char>> {
// ...
};
但是后来...
template <typename T>
struct bad {
using type = T;
};
// 如预期那样工作
f<box<char>>::type;
// 即使 bad<char> 显然是一个boxed char,也不工作
f<bad<char>>::type;
相反,我们可能需要进行更复杂的操作,如:
template <typename T>
struct f_impl;
template <>
struct f_impl<char> {
using type = ...;
};
template <typename B>
struct f
: f_impl<typename B::type>
{ };
f<box<char>>::type; // 工作
f<bad<char>>::type; // 也工作
有趣的是,boxed 类型和 thunks 之间有很多相似之处。实际上,thunk不过是通过 suspending 一个元函数形成的boxed类型。因此,每当boxed类型被期望时,都可以使用 thunk 代替。
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00- QQwen3-Coder-Next2026年2月4日,正式发布的Qwen3-Coder-Next,一款专为编码智能体和本地开发场景设计的开源语言模型。Python00
xw-cli实现国产算力大模型零门槛部署,一键跑通 Qwen、GLM-4.7、Minimax-2.1、DeepSeek-OCR 等模型Go06
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin08
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00