C++ 域

在 1.0 版本中添加。

C++ 域(名称 cpp)支持编写 C++ 项目文档。

声明实体的指令

提供以下指令。所有声明都可以以可见性声明(publicprivateprotected)开头。

.. cpp:class:: class specifier
.. cpp:struct:: class specifier

描述类/结构,可能指定继承,例如

.. cpp:class:: MyClass : public MyBase, MyOtherBase

cpp:classcpp:struct 之间的区别只是形式上的:输出中呈现的前缀和索引中显示的说明符。

类可以直接在嵌套作用域中声明,例如

.. cpp:class:: OuterScope::MyClass : public MyBase, MyOtherBase

可以声明类模板

.. cpp:class:: template<typename T, std::size_t N> std::array

或换行

.. cpp:class:: template<typename T, std::size_t N> \
               std::array

可以声明完全和部分模板特例化

.. cpp:class:: template<> \
               std::array<bool, 256>

.. cpp:class:: template<typename T> \
               std::array<T, 42>

在 2.0 版本中添加:cpp:struct 指令。

.. cpp:function:: (member) function prototype

描述函数或成员函数,例如

.. cpp:function:: bool myMethod(int arg1, std::string arg2)

   A function with parameters and types.

.. cpp:function:: bool myMethod(int, double)

   A function with unnamed parameters.

.. cpp:function:: const T &MyClass::operator[](std::size_t i) const

   An overload for the indexing operator.

.. cpp:function:: operator bool() const

   A casting operator.

.. cpp:function:: constexpr void foo(std::string &bar[2]) noexcept

   A constexpr function.

.. cpp:function:: MyClass::MyClass(const MyClass&) = default

   A copy constructor with default implementation.

也可以描述函数模板

.. cpp:function:: template<typename U> \
                  void print(U &&u)

以及函数模板特例化

.. cpp:function:: template<> \
                  void print(int i)
:single-line-parameter-list: (no value)

确保函数的参数将放在一行逻辑文本上,覆盖 cpp_maximum_signature_line_lengthmaximum_signature_line_length

在 7.1 版本中添加。

.. cpp:member:: (成员) 变量 声明
.. cpp:var:: (成员) 变量 声明

描述变量或成员变量,比如

.. cpp:member:: std::string MyClass::myMember

.. cpp:var:: std::string MyClass::myOtherMember[N][M]

.. cpp:member:: int a = 42

变量模板也可以被描述

.. cpp:member:: template<class T> \
                constexpr T pi = T(3.1415926535897932385)
.. cpp:type:: typedef 声明
.. cpp:type:: 名称
.. cpp:type:: 类型 别名 声明

描述类型如同在 typedef 声明, type alias 声明, 或仅仅是未指定类型的名称,比如

.. cpp:type:: std::vector<int> MyList

   A typedef-like declaration of a type.

.. cpp:type:: MyContainer::const_iterator

   Declaration of a type alias with unspecified type.

.. cpp:type:: MyType = std::unordered_map<int, std::string>

   Declaration of a type alias.

类型别名也可以是模板化的

.. cpp:type:: template<typename T> \
              MyContainer = std::vector<T>

示例被渲染如下。

typedef std::vector<int> MyList

类型类似 typedef 的声明。

type MyContainer::const_iterator

声明具有未指定类型的类型别名。

using MyType = std::unordered_map<int, std::string>

类型别名声明。

模板<typename T>
使用 MyContainer = std::vector<T>
.. cpp:enum:: 非作用域 枚举 声明
.. cpp:enum-struct:: 作用域 枚举 声明
.. cpp:enum-class:: 作用域 枚举 声明

描述(作用域)枚举,可能指定底层类型。在非作用域范围内声明的任何枚举器将在枚举作用域和父作用域中进行声明。示例

.. cpp:enum:: MyEnum

   An unscoped enum.

.. cpp:enum:: MySpecificEnum : long

   An unscoped enum with specified underlying type.

.. cpp:enum-class:: MyScopedEnum

   A scoped enum.

.. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type<MySpecificEnum>::type

   A scoped enum with non-default visibility, and with a specified
   underlying type.
.. cpp:enumerator:: 名称
.. cpp:enumerator:: 名称 = 常量

描述枚举器,可以不用定义其值,例如,

.. cpp:enumerator:: MyEnum::myEnumerator

.. cpp:enumerator:: MyEnum::myOtherEnumerator = 42
.. cpp:union:: 名称

描述联合。

在 1.8 版本中添加。

.. cpp:concept:: 模板参数列表 名称

警告

对 concept 的支持仍处于实验阶段。其建立在当前草案标准和概念技术规范的基础之上。随着发展,这些功能可能会发生改变。

描述概念。概念必须有且仅有一个模板参数列表。名称可以是嵌套名称。示例

.. cpp:concept:: template<typename It> std::Iterator

   Proxy to an element of a notional sequence that can be compared,
   indirected, or incremented.

   **Notation**

   .. cpp:var:: It r

      An lvalue.

   **Valid Expressions**

   - :cpp:expr:`*r`, when :cpp:expr:`r` is dereferenceable.
   - :cpp:expr:`++r`, with return type :cpp:expr:`It&`, when
     :cpp:expr:`r` is incrementable.

渲染内容如下

模板<typename It>
概念 std::迭代器

可比较、可间接寻址或可增量的概念序列元素代理。

符号

It r

一个左值。

有效表达式

  • *r, 当r可间接寻址时。

  • ++r,返回类型It&,当r可增量时。

在版本 1.5 中添加。

选项

某些指令支持选项

  • :no-index-entry::no-contents-entry:,请参阅 基本标记

  • :tparam-line-spec:,用于模板化声明。如果指定,每个模板参数将分别显示在一行上。

    在版本 1.6 中添加。

匿名实体

C++ 支持匿名命名空间、类、枚举和联合。为了文档的缘故,必须为它们指定以 @ 开始的名称,例如, @42@data。这些名称还可用于交叉引用和(类型)表达式,但即使省略,嵌套符号也依然可找到。 @... 名称始终显示为 [匿名](可能显示为链接)。

示例

.. cpp:class:: Data

   .. cpp:union:: @data

      .. cpp:var:: int a

      .. cpp:var:: double b

Explicit ref: :cpp:var:`Data::@data::a`. Short-hand ref: :cpp:var:`Data::a`.

将显示为

数据
并集 [匿名]
int a
double b

显式 ref: Data::[anonymous]::a,简写 ref: Data::a

在 1.8 版本中添加。

别名声明

有时,亦可能将声明列于主要文档之外,例如,在创建类的接口概要时。以下指令可用于此目的。

.. cpp:alias:: name or function signature

插入一个或多个别名声明。每个实体可以像在 cpp:any 角色中指定一样。如果给定的是函数名称(与完整签名相反),那么将列出该函数的所有重载。

例如

.. cpp:alias:: Data::a
               overload_example::C::f

变成

int a
void f(double d) const
void f(double d)
void f(int i)
void f()

.. cpp:alias:: void overload_example::C::f(double d) const
               void overload_example::C::f(double d)

变成

void f(double d) const
void f(double d)

已在 2.0 版本中添加。

选项

:maxdepth: int

还插入嵌套的声明,其深度达到指定深度。如果深度无限,则使用 `0`,如果仅指定声明,则使用 `1`。默认为 `1`。

已在 3.5 版本中添加。

:noroot:

跳过指定的声明,仅渲染嵌套的声明。需要 `maxdepth` 为 `0` 或至少为 `2`。

已在 3.5 版本中添加。

受约束模板

警告

对 concept 的支持仍处于实验阶段。其建立在当前草案标准和概念技术规范的基础之上。随着发展,这些功能可能会发生改变。

注意

Sphinx 目前不支持 `requires` 子句。

占位符

声明可使用概念的名称来引入受约束模版参数,或使用关键字 `auto` 来引入不受约束模版参数。

.. cpp:function:: void f(auto &&arg)

   A function template with a single unconstrained template parameter.

.. cpp:function:: void f(std::Iterator it)

   A function template with a single template parameter, constrained by the
   Iterator concept.

模板引言

可以使用“模板引言”而不是模板参数列表声明简单的受约束函数或类模板。

.. cpp:function:: std::Iterator{It} void advance(It &it)

    A function template with a template parameter constrained to be an
    Iterator.

.. cpp:class:: std::LessThanComparable{T} MySortedContainer

    A class template with a template parameter constrained to be
    LessThanComparable.

它们按以下方式渲染。

std::Iterator{It}
void advance(It &it)

函数模板,其模板参数受约束为 Iterator。

std::LessThanComparable{T}
class MySortedContainer

模板参数受限于 LessThanComparable 的类模板。

但请注意,对于参数兼容性不执行任何检查。例如,Iterator{A, B, C} 作为简介是可以接受的,即使它并不符合有效的 C++。

内联表达式和类型

:cpp:expr:
:cpp:texpr:

插入 C++ 表达式或类型,作为内联代码 (cpp:expr) 或内联文本 (cpp:texpr)。比如

.. cpp:var:: int a = 42

.. cpp:function:: int f(int i)

An expression: :cpp:expr:`a * f(a)` (or as text: :cpp:texpr:`a * f(a)`).

A type: :cpp:expr:`const MySortedContainer<int>&`
(or as text :cpp:texpr:`const MySortedContainer<int>&`).

将呈现如下:

int a = 42
int f(int i)

表达式:a * f(a)(或作为文本:a * f(a))。

A 类型:const MySortedContainer<int>&(或作为文本const MySortedContainer<int>&)。

1.7 版新增: cpp:expr 角色。

1.8 版新增: cpp:texpr 角色。

名称空间

使用 C++ 域中的声明默认为放在全局范围内。可以使用三个名称空间指令更改当前范围。它们管理一个堆栈声明,其中 cpp:namespace 重置堆栈并更改给定范围。

cpp:namespace-push 指令将范围更改为当前范围的给定内部范围。

cpp:namespace-pop 指令撤消最近的 cpp:namespace-push 指令。

.. cpp:namespace:: scope specification

将后续对象的当前范围更改为给定范围,并重置名称空间指令堆栈。请注意,名称空间不需要对应 C++ 名称空间,但可以在类名称中结束,例如,

.. cpp:namespace:: Namespace1::Namespace2::SomeClass::AnInnerClass

所有后续对象都将定义为,仿佛它们的名称已声明为附加范围。随后的交叉引用将从当前范围开始搜索。

NULL0nullptr 用作范围后,范围将更改为全局范围。

名称空间声明也可以是模板化的,例如,

.. cpp:class:: template<typename T> \
               std::vector

.. cpp:namespace:: template<typename T> std::vector

.. cpp:function:: std::size_t size() const

size 声明为类模板 std::vector 的成员函数。等效地,可以使用以下方式声明它

.. cpp:class:: template<typename T> \
               std::vector

   .. cpp:function:: std::size_t size() const

.. cpp:class:: template<typename T> \
               std::vector
.. cpp:namespace-push:: scope specification

相对于当前范围更改范围。例如,在以下之后

.. cpp:namespace:: A::B

.. cpp:namespace-push:: C::D

当前作用域将为 A::B::C::D

在版本 1.4 中添加。

.. cpp:namespace-pop::

撤消之前的 cpp:namespace-push 指令(而非仅仅弹出作用域)。例如,之后

.. cpp:namespace:: A::B

.. cpp:namespace-push:: C::D

.. cpp:namespace-pop::

当前作用域将为 A::B而非 A::B::C)。

如果没有使用先前的 cpp:namespace-push 指令,而仅使用了 cpp:namespace 指令,那么当前作用域将重置为全局作用域。即,.. cpp:namespace:: A::B 等效于

.. cpp:namespace:: nullptr

.. cpp:namespace-push:: A::B

在版本 1.4 中添加。

信息字段列表

用于声明实体的所有 C++ 指令都支持以下信息字段(请参阅 信息字段列表

  • tparam:模板参数的描述。

此外,cpp:function 指令支持以下字段

  • paramparameterargargument:参数的描述。

  • returnsreturn:返回值的描述。

  • retvalretvals:描述函数结果的 returns 的备用字段。

  • throwsthrowexception:可能抛出的异常的描述。

在版本 4.3 中添加: retval 字段类型。

交叉引用

这些角色链接到给定的声明类型

:cpp:any:
:cpp:class:
:cpp:struct:
:cpp:func:
:cpp:member:
:cpp:var:
:cpp:type:
:cpp:concept:
:cpp:enum:
:cpp:enumerator:

按名称引用 C++ 声明(有关详情,请参见下方)。该名称必须相对于链接位置正确限定。

2.0 版中添加:cpp:struct 角色作为 cpp:class 角色的别名。

带有模板参数/参数的引用的注释

这些角色遵循 sphinx 交叉引用语法 规则。这意味着在引用(部分)模板专业化时必须小心,例如,如果链接类似于此: :cpp:class:`MyClass<int>`。这解释为 int,标题为 MyClass。在这种情况下,使用反斜杠转义开口角括号,如下所示::cpp:class:`MyClass\<int>`

如果不需要自定义标题,则可以将这些角色用于内联表达式,cpp:exprcpp:texpr,其中不需要转义尖括号。

没有模板参数和模板参数的声明

要链接到非模板化声明,名称必须是嵌套名称,例如,fMyClass::f

重载(成员)函数

当(成员)函数只通过其名称参考时,该引用将指向一个任意匹配的重载。cpp:anycpp:func 角色使用的是另一种格式,仅是一个完整函数声明。这会解决与重载的确切匹配。作为示例,考虑以下类声明

class C
void f(double d) const
void f(double d)
void f(int i)
void f()

使用 cpp:func 角色的引用

注意 add_function_parentheses 配置变量不影响具体重载引用。

模板化声明

假设以下声明。

class Wrapper
template<typename TOuter>
class Outer
template<typename TInner>
class Inner

总的来说,引用必须包括模板参数声明,以及限定名称前缀的模板参数。例如

  • 模板&lt;类型名 TOuter> Wrapper::Outer (模板&lt;类型名 TOuter> Wrapper::Outer)

  • 模板&lt;类型名 TOuter> 模板&lt;类型名 TInner> Wrapper::Outer<TOuter>::Inner (模板&lt;类型名 TOuter> 模板&lt;类型名 TInner> Wrapper::Outer<TOuter>::Inner)

目前仅当模板参数标识符为相等字符串时,查找才成功。即,模板&lt;类型名 UOuter> Wrapper::Outer 将不起作用。

作为简短记法,如果省略模板参数列表,则查找将假定主模板或非模板,但不是部分模板特化。这意味着以下引用也可以正常工作

(完整)模板特化

假设以下声明。

模板<类型名 TOuter>
Outer
模板<类型名 TInner>
Inner
模板<>
Outer<int>
模板<typename TInner>
Inner
模板<>
Inner<bool>

通常,引用必须包含每个模板参数列表的模板参数列表。因此,上面的完全专门化可以使用 template\<> Outer\<int>template<> Outer<int>)和 template\<> template\<> Outer\<int>::Inner\<bool>template<> template<> Outer<int>::Inner<bool>)进行引用。你可以使用简略的书写方式省略空模板参数列表,比如 Outer\<int>Outer<int>)和 Outer\<int>::Inner\<bool>Outer<int>::Inner<bool>)。

部分模板专门化

假设有以下声明。

模板<typename T>
Outer<T*>

对部分专业化的引用必须始终包括模板参数列表,例如,template\<typename T> Outer\<T*> (template<typename T> Outer<T*>)。目前,仅当模板参数标识符为相等的字符串时,查找才成功。

配置变量

请参阅C++ 区域选项