Boost.Hana-zh

优质
小牛编辑
138浏览
2023-12-01

Boost.Hana 中文文档,翻译自 http://boostorg.github.io/hana/ 版本: Boost.Hana 1.2.0

元编程标准库中文文档

  • Hana 是一个元编程库,提供异构容器和算法,用于类型和值的计算。用户手册在这里
  • Hana 提供了异构容器和算法,合并了异构计算和编译期计算。参考文档在这里
  • Hana 是一个头文件库,利用C++14技术和惯用法编写,不依赖于其它库。头文件文档在这里
  • 应用Hana库是很容易的,它背后的构建与技术也可能有必要加以了解。这些想法在这里

快速访问:https://coding.net/u/freezestudio/p/Boost.Hana-zh/git

概览

#include <boost/hana.hpp>
#include <cassert>
#include <string>
namespace hana = boost::hana;
using namespace hana::literals;

struct Fish { std::string name; };
struct Cat  { std::string name; };
struct Dog  { std::string name; };

int main() {
  // 持有异构对象的序列和操纵它们的算法。
  auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});
  auto names = hana::transform(animals, [](auto a) {
    return a.name;
  });
  assert(hana::reverse(names) == hana::make_tuple("Snoopy", "Garfield", "Nemo"));

  // `animals`承载的字符串不是常量表达式,即便如此,因为长度是`constexpr`的,故此不会丢失编译时信息。
  static_assert(hana::length(animals) == 3u, "");

  //类型的计算可以使用与普通C++相同的语法来执行。 不管相信与否,一切都在编译时完成。
  auto animal_types = hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Cat&>, hana::type_c<Dog*>);
  auto animal_ptrs = hana::filter(animal_types, [](auto a) {
    return hana::traits::is_pointer(a);
  });
  static_assert(animal_ptrs == hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Dog*>), "");

  // 还有更多可轻松获取的好处,包括:
  // 1. 访问元组的语法更清晰
  static_assert(animal_ptrs[0_c] == hana::type_c<Fish*>, "");
  static_assert(animal_ptrs[1_c] == hana::type_c<Dog*>, "");

  // 2. 很轻松地在编译时展开循环
  std::string s;
  hana::int_c<10>.times([&]{ s += "x"; });
  // 相当于 s += "x"; s += "x"; ... s += "x";

  // 3. 检查表达式的有效性也很方便
  //    原先为此通常需要基于复杂的SFINAE技巧才行
  auto has_name = hana::is_valid([](auto&& x) -> decltype((void)x.name) { });
  static_assert(has_name(animals[0_c]), "");
  static_assert(!has_name(1), "");
}

文档

可以在线浏览 http://boostorg.github.io/hana。也可以从gh-pages分支检出一份离线文档。为避免覆盖当前目录,最好clonegh-pages分支到一个像doc/html这样的一个子目录中:

git clone http://github.com/boostorg/hana --branch=gh-pages --depth=1 doc/html

发布后,doc/html将包含与可在线使用[]的完全相同的静态网站。 注意,doc/html会自动被Git忽略,所以更新文档不会搞乱你的索引。

独立使用Hana

很容易将Hana设置为只为你所用。首先,需要安装CMake。而后,切换(cd)到项目根目录并新建build子目录:

mkdir build
cd build
cmake ..

通常,系统自带的编译器过于陈旧,你可能需要指定的编译器:

cmake .. -DCMAKE_CXX_COMPILER=/path/to/compiler

一般来说,这样就能很好地工作了。但是,在一些系统上,标准库和/或编译器默认不支持C++14。这样的话查看wiki,那里有更多针对不同系统的设置信息。

通常,Hana会尝试在你的系统上查找Boost头文件,没有Boost头文件Hana仍然能够工作,只不过将会禁用少数几个依赖于Boost的测试。但是如果你想要Hana使用自定义安装的Boost,你需要指定自定义安装Boost的位置:

cmake .. -DCMAKE_CXX_COMPILER=/path/to/compiler -DBOOST_ROOT=/path/to/boost

现在可以构建与运行单元测试及示例了:

cmake --build . --target check

先说清楚,编译单元测试是相当耗时的,也需要大量的内存占用,特别是对外部适配器的测试。 这是由于Hana的单元测试是非常彻底的,而且其他库中的异构序列往往具有更巨量的编译消耗。

一些可选的目标仅在你的系统上安装有相应的软件才会启用。比如,生成文件需要系统安装了Doxygen。CMake在生成期间会打印出哪些目标没有启用。你可以根据这些信息安装相应的软件后再重新CMake

提示

help 选项可列出需要的软件。

若想添加单元测试或者示例,将源文件添加到test/example/目录下重新CMake即可。假设相对路径从项目到新源文件的根目录是path/to/file.cpp。 重新运行CMake生成步骤后,将会创建一个名为path.to.file的新目标,并且还将创建相同名称的测试。像这样,

cd build # Go back to the build directory
cmake --build . --target path.to.file # Builds the program associated to path/to/file.cpp
ctest -R path.to.file # Runs the program as a test

Sublime Text用户的提示

使用此hana.sublime-project支持文件,选择[Hana] Build current file 构建系统,当看到目标被关联到(like a test or an example), 按⌘B键编译, 或者按⇧⌘B键编译并运行。

项目结构

项目有几个子目录。

  • benchmark目录存放编译时和运行时的基准测试内容,以确保库的速度与所说的那快。 基准测试中的代码主要以eRuby模板的形式编写。 模板用于生成C++文件,以进行编译编译和执行统计。
  • cmake目录存放用于编译系统所用的CMake模块及其它脚本。
  • doc目录存放生成文件所需的配置文件。Git会自动忽略doc/html子目录;如上所述,您可以方便地将gh-pages分支克隆到该目录以存储本地文档副本。
  • example目录存放所有教程与参考示例的源代码。
  • experimental目录存放的实验性功能有可能在适当的时候加入到库中。
  • include目录存放库的源代码,它们只有头文件。
  • test目录存放单元测试源代码。

相关资料

  • CppCon 2015 有关元编程和Hana的讨论 (幻灯片/视频)
  • C++Now 2015 有关元编程和Hana的讨论 (幻灯片)
  • CppCon 2014 有关Hana的讨论 (幻灯片/视频)
  • MPL11 库,Hana的起源
  • C++Now 2014 有关MPL11的讨论 (幻灯片/视频)
  • Louis Dionne的学士学位论文经由类别来形式化C++元编程(a formalization of C++ metaprogramming through category)理论。 论文在这里, 相关演示文稿的幻灯片在这里。很不幸,都是法语的。