C++ 域

版本 1.0 新增。

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

声明实体的指令

以下指令可用。所有声明都可以以可见性声明(publicprivateprotected)开始。

.. cpp:class:: 说明符
.. cpp:struct:: 说明符

描述一个类/结构体,可能包含继承规范,例如,

.. 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:: (成员) 函数 原型

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

.. 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: (无 值)

确保函数的参数将在一个逻辑行上发出,覆盖 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 声明、类型别名声明,或只是一个未指定类型的类型名称,例如,

.. 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>

类型别名声明。

template<typename T>
using 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:: 模板参数列表 名称

警告

对概念的支持是实验性的。它基于当前的草案标准和概念技术规范。这些特性可能会随着它们的发展而改变。

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

.. 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.

这将呈现如下

template<typename It>
concept std::Iterator

可比较、可间接访问或可递增的假想序列元素的代理。

表示法

It r

一个左值。

有效表达式

  • *r,当 r 可解引用时。

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

版本 1.5 新增。

选项

某些指令支持选项

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

  • :tparam-line-spec:,用于模板化声明。如果指定,每个模板参数将独立成行。

    版本 1.6 中新增。

匿名实体

C++ 支持匿名命名空间、类、枚举和联合体。为了文档化,它们必须被赋予一个以 @ 开头的名称,例如 @42@data。这些名称也可以用于交叉引用和(类型)表达式,尽管即使省略了嵌套符号也会找到它们。@... 名称将始终渲染为 [anonymous](可能是一个链接)。

示例

.. 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`.

这将渲染为

class Data
union [anonymous]
int a
double b

显式引用:Data::[anonymous]::a。简写引用:Data::a

版本 1.8 中新增。

别名声明

有时,在主文档之外列出声明可能很有用,例如,在创建类接口的概要时。可以使用以下指令来实现此目的。

.. cpp:alias:: 名称 函数 签名

插入一个或多个别名声明。每个实体都可以像在 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: 整型

插入嵌套声明,最大深度由给定值决定。0 表示无限深度,1 表示仅提及的声明。默认为 1。

版本 3.5 中新增。

:noroot:

跳过所提及的声明,仅渲染嵌套声明。要求 maxdepth 为 0 或至少为 2。

版本 3.5 中新增。

受限模板

警告

对概念的支持是实验性的。它基于当前的草案标准和概念技术规范。这些特性可能会随着它们的发展而改变。

注意

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)

一个模板函数,其模板参数被限制为迭代器。

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))。

一个类型: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:: 范围 规范

将后续对象的当前范围更改为给定范围,并重置命名空间指令堆栈。请注意,命名空间不需要与 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:: 范围 规范

相对于当前范围更改范围。例如,在

.. 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 指令还支持以下字段

  • param, parameter, arg, argument: 参数描述。

  • returns, return: 返回值的描述。

  • retval, retvalsreturns 的替代品,用于描述函数的结果。

  • throws, throw, exception: 可能抛出的异常的描述。

版本 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

通常,引用必须包含模板参数声明,以及合格名称前缀的模板实参。例如

  • template\<typename TOuter> Wrapper::Outer (template<typename TOuter> Wrapper::Outer)

  • template\<typename TOuter> template\<typename TInner> Wrapper::Outer<TOuter>::Inner (template<typename TOuter> template<typename TInner> Wrapper::Outer<TOuter>::Inner)

目前,只有当模板参数标识符是相同的字符串时,查找才能成功。也就是说,template\<typename UOuter> Wrapper::Outer 将不起作用。

作为简写符号,如果省略模板参数列表,则查找将假定为主要模板或非模板,但不是部分模板特化。这意味着以下引用也适用

(完整)模板特化

假设有以下声明。

template<typename TOuter>
class Outer
template<typename TInner>
class Inner
template<>
class Outer<int>
template<typename TInner>
class Inner
template<>
class 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>)。

部分模板特化

假设有以下声明。

template<typename T>
class Outer<T*>

对部分特化的引用必须始终包含模板参数列表,例如 template\<typename T> Outer\<T*> (template<typename T> Outer<T*>)。目前,查找只有在模板参数标识符是相同的字符串时才能成功。

配置变量

参见 C++ 域选项