Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: migrate cpp/templates cpp/exceptions from cppref
  • Loading branch information
momo773510 committed Dec 5, 2025
commit a69c304032ee5b6188d3478533b487736f23c1cf
82 changes: 82 additions & 0 deletions src/content/docs/cpp/language/exceptions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
title: Exceptions
cppdoc:
keys: ["cpp.lang.exceptions"]
---

import { Decl, DeclDoc } from "@components/decl-doc";
import { Desc, DescList, DocLink } from '@components/index';
import { Revision, RevisionBlock } from "@components/revision";
import { DR, DRList } from "@components/defect-report";
import { ParamDoc, ParamDocList } from "@components/param-doc";
import { FeatureTestMacro, FeatureTestMacroValue } from "@components/feature-test-macro";

Exception handling provides a way of transferring control and information from some point in the execution of a program to a handler associated with a point previously passed by the execution (in other words, exception handling transfers control up the call stack).

Evaluating a <DocLink src="cpp/language/throw.html#throw_expressions">`throw` expression</DocLink> will throw an exception. Exceptions can also be thrown in <DocLink src="cpp/language/throw.html#throw_expressions">other contexts</DocLink>.

In order for an exception to be caught, the `throw` expression has to be inside a <DocLink src="cpp/language/try">`try` block</DocLink>, and the `try` block has to contain a <DocLink src="cpp/language/catch">handler</DocLink> that matches the type of the exception object.

When declaring a function, the following specification(s) may be provided to limit the types of the exceptions a function may throw:

- <Revision since="C++17"><DocLink src="cpp/language/cpp/language/except_spec">dynamic exception specifications</DocLink></Revision>
- <Revision since="C++11"><DocLink src="cpp/language/cpp/language/noexcept_spec">noexcept specifications</DocLink></Revision>

Errors that arise during exception handling are handled by <DocLink src="cpp/error/terminate">`std::terminate`</DocLink> and <Revision since="C++17"><DocLink src="cpp/error/unexpected">`std::unexpected`</DocLink></Revision>.

## Usage

While `throw` expression can be used to transfer control to an arbitrary block of code up the execution stack, for arbitrary reasons (similar to <DocLink src="cpp/utility/program/longjmp">`std::longjmp`</DocLink>), its intended usage is error handling.

### Error handling

Throwing an exception is used to signal errors from functions, where "errors" are typically limited to only the following[^1] [^2] [^3]:

1. Failures to meet the postconditions, such as failing to produce a valid return value object.
2. Failures to meet the preconditions of another function that must be called.
3. (for non-private member functions) Failures to (re)establish a class invariant.

In particular, this implies that the failures of constructors (see also <DocLink src="cpp/language/raii">RAII</DocLink>) and most operators should be reported by throwing exceptions.

In addition, so-called *wide contract* functions use exceptions to indicate unacceptable inputs, for example, <DocLink src="cpp/string/basic_string/at">`std::basic_string::at`</DocLink> has no preconditions, but throws an exception to indicate index out of range.

### Exception safety

After the error condition is reported by a function, additional guarantees may be provided with regards to the state of the program. The following four levels of exception guarantee are generally recognized[^4] [^5] [^6], which are strict supersets of each other:

1. *Nothrow (or nofail) exception guarantee* — the function never throws exceptions. Nothrow (errors are reported by other means or concealed) is expected of <DocLink src="cpp/language/destructor">destructors</DocLink> and other functions that may be called during stack unwinding. <Revision since="C++11">The <DocLink src="cpp/language/destructor">destructors</DocLink> are <DocLink src="cpp/language/noexcept">`noexcept`</DocLink> by default.</Revision> Nofail (the function always succeeds) is expected of swaps, <DocLink src="cpp/language/move_constructor">move constructors</DocLink>, and other functions used by those that provide strong exception guarantee.
2. *Strong exception guarantee* — If the function throws an exception, the state of the program is rolled back to the state just before the function call (for example, <DocLink src="cpp/container/vector/push_back">`std::vector::push_back`</DocLink>).
3. *Basic exception guarantee* — If the function throws an exception, the program is in a valid state. No resources are leaked, and all objects' invariants are intact.
4. *No exception guarantee* — If the function throws an exception, the program may not be in a valid state: resource leaks, memory corruption, or other invariant-destroying errors may have occurred.

Generic components may, in addition, offer *exception-neutral guarantee*: if an exception is thrown from a template parameter (e.g. from the `Compare` function object of <DocLink src="cpp/algorithm/sort">`std::sort`</DocLink> or from the constructor of `T` in <DocLink src="cpp/memory/shared_ptr/make_shared">`std::make_shared`</DocLink>), it is propagated, unchanged, to the caller.

## Exception objects

While objects of any complete type and cv pointers to `void` may be thrown as exception objects, all standard library functions throw unnamed objects by value, and the types of those objects are derived (directly or indirectly) from <DocLink src="cpp/error/exception">`std::exception`</DocLink>. User-defined exceptions usually follow this pattern.[^7] [^8] [^9]

To avoid unnecessary copying of the exception object and object slicing, the best practice for handlers is to catch by reference.[^10] [^11] [^12] [^13]

## Notes

<FeatureTestMacro name="__cpp_constexpr_exceptions">
<FeatureTestMacroValue value="202411L" since="C++26">
`constexpr` exceptions
</FeatureTestMacroValue>
</FeatureTestMacro>

## External links

[^1]: H. Sutter (2004) [When and How to Use Exceptions](https://www.drdobbs.com/when-and-how-to-use-exceptions/184401836) in Dr. Dobb's
[^2]: H. Sutter, A. Alexandrescu (2004) "C++ Coding Standards" Item 70
[^3]: C++ Core Guidelines [I.10: Use exceptions to signal a failure to perform a required task](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-except)
[^4]: B. Stroustrup (2000) "The C++ Programming Language" [Appendix E](https://stroustrup.com/3rd_safe.pdf)
[^5]: H. Sutter (2000) "Exceptional C++"
[^6]: D. Abrahams (2001) ["Exception Safety in Generic Components"](https://www.boost.org/community/exception_safety.html)
[^7]: D. Abrahams (2001) ["Error and Exception Handling"](https://www.boost.org/community/error_handling.html)
[^8]: isocpp.org Super-FAQ ["What should I throw?"](https://isocpp.org/wiki/faq/exceptions#what-to-throw)
[^9]: C++ Core Guidelines [E.14: Use purpose-designed user-defined types as exceptions (not built-in types)](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Re-exception-types)
[^10]: C++ Core Guidelines [E.15: Throw by value, catch exceptions from a hierarchy by reference](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Re-exception-ref)
[^11]: S. Meyers (1996) "More Effective C++" Item 13
[^12]: isocpp.org Super-FAQ ["What should I catch?"](https://isocpp.org/wiki/faq/exceptions#what-to-catch)
[^13]: H. Sutter, A. Alexandrescu (2004) "C++ Coding Standards" Item 73
282 changes: 282 additions & 0 deletions src/content/docs/cpp/language/templates.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
---
title: Templates
cppdoc:
keys: ["cpp.lang.templates"]
---

import { Decl, DeclDoc } from "@components/decl-doc";
import { Desc, DescList, DocLink } from '@components/index';
import { Revision, RevisionBlock } from "@components/revision";
import { DR, DRList } from "@components/defect-report";
import { ParamDoc, ParamDocList } from "@components/param-doc";

A template is a C++ entity that defines one of the following:

- a family of classes (<DocLink src="cpp/language/class_template">class template</DocLink>), which may be <DocLink src="cpp/language/member_template">nested classes</DocLink>
- a family of functions (<DocLink src="cpp/language/function_template">function template</DocLink>), which may be <DocLink src="cpp/language/member_template">member functions</DocLink>


- <Revision since="C++11">an alias to a family of types (<DocLink src="cpp/language/type_alias">alias template</DocLink>)</Revision>


- <Revision since="C++14">a family of variables (<DocLink src="cpp/language/variable_template">variable template</DocLink>)</Revision>


- <Revision since="C++20">a concept (<DocLink src="cpp/language/constraints">constraints and concepts</DocLink>)</Revision>

Templates are parameterized by one or more <DocLink src="cpp/language/template_parameters">template parameters</DocLink>, of three kinds: type template parameters, constant template parameters, and template template parameters.

When template arguments are provided, or, for <DocLink src="cpp/language/function_template#Template_argument_deduction">function</DocLink> <Revision since="C++17">and <DocLink src="cpp/language/class_template_argument_deduction">class</DocLink></Revision> templates only, deduced, they are substituted for the template parameters to obtain a *specialization* of the template, that is, a specific type or a specific function lvalue.

Specializations may also be provided explicitly: <DocLink src="cpp/language/template_specialization">full specializations</DocLink> are allowed for class<Revision since="C++14">, <DocLink src="cpp/language/template_specialization">variable</DocLink></Revision> and function templates, <DocLink src="cpp/language/partial_specialization">partial specializations</DocLink> are only allowed for class templates<Revision since="C++14"> and <DocLink src="cpp/language/partial_specialization">variable templates</DocLink></Revision>.

When a class template specialization is referenced in context that requires a complete object type, or when a function template specialization is referenced in context that requires a function definition to exist, the template is *instantiated* (the code for it is actually compiled), unless the template was already explicitly specialized or explicitly instantiated. Instantiation of a class template does not instantiate any of its member functions unless they are also used. At link time, identical instantiations generated by different translation units are merged.

The definition of a class template must be visible at the point of implicit instantiation, which is why template libraries typically provide all template definitions in the headers (e.g., [most boost libraries are header-only](https://www.boost.org/doc/libs/release/more/getting_started/unix-variants.html#header-only-libraries)).

## Syntax

<DeclDoc>
<Decl slot="decl">
```cpp
template <parameter-list> requires-clause(optional)</span> declaration
```
</Decl>
</DeclDoc>

<DeclDoc>
<Decl slot="decl">
```cpp
export template <parameter-list> declaration
```
</Decl>
<Revision until="C++11"></Revision>
</DeclDoc>

<DeclDoc>
<Decl slot="decl">
```cpp
template <parameter-list> concept concept-name = constraint-expression;
```
</Decl>
<Revision since="C++20"></Revision>
</DeclDoc>


<ParamDocList>
<ParamDoc name="parameter-list">
a non-empty comma-separated list of the template parameters, each of which is either constant parameter, a type parameter, a template parameter, or a parameter pack of any of those(since C++11).
</ParamDoc>
<ParamDoc name="requires-clause">
(since C++20) a requires-clause that specifies the constraints on the template arguments.
</ParamDoc>
<ParamDoc name="declaration">
declaration of a class (including struct and union), a member class or member enumeration type, a function or member function, a static data member at namespace scope, a variable or static data member at class scope(since C++14), or an alias template(since C++11). It may also define a template specialization.
</ParamDoc>
<ParamDoc name="concept-name">
concept-name
</ParamDoc>
<ParamDoc name="constraint-expression">
see constraints and concepts
</ParamDoc>
</ParamDocList>

<RevisionBlock until="C++11">export was an optional modifier which declared the template as exported (when used with a class template, it declared all of its members exported as well). Files that instantiated exported templates did not need to include their definitions: the declaration was sufficient. Implementations of export were rare and disagreed with each other on details. </RevisionBlock>
> This section is incomplete.\
> **Reason:** core syntax, template parameters, and instantiations, take content common between class_template and function_template

## Template identifiers

A template identifier has one of the following syntaxes:

<DeclDoc>
<Decl slot="decl">
```cpp
template-name<template-argument-list(optional)>
```
</Decl>

A *simple template identifier*.
</DeclDoc>
<DeclDoc>
<Decl slot="decl">
```cpp
operator op<template-argument-list(optional)>
```
</Decl>

An operator function template identifier.
</DeclDoc>
<DeclDoc>
<Decl slot="decl">
```cpp
operator "" identifier<template-argument-list(optional)>
```
</Decl>

A literal operator function template identifier. <Revision since="C++11" traits={[{ trait: "deprecated", since:"C++23"}]}></Revision>
</DeclDoc>
<DeclDoc>
<Decl slot="decl">
```cpp
operator user-defined-string-literal<template-argument-list(optional)>
```
</Decl>

A user-defined string literal operator. <Revision since="C++11"></Revision>
</DeclDoc>

A simple template identifier that names a class template specialization names a class.

A template identifier that names an alias template specialization names a type.

A template identifier that names a function template specialization names a function.

If all following conditions are satisfied, a template identifier is *valid*:

- There are at most as many arguments as there are parameters<Revision since="C++11"> or a parameter is a template <DocLink src="cpp/language/parameter_pack">parameter pack</DocLink></Revision>
- There is an argument for each non-deducible<Revision since="C++11"> non-pack</Revision> parameter that does not have a default template argument
- Each template argument matches the corresponding template parameter
- Substitution of each template argument into the following template parameters (if any) succeeds

- <Revision since="C++20"> If the template identifier is <DocLink src="/cpp/language/dependent_name">non-dependent</DocLink>, the associated constraints are satisfied as specified below</Revision>

An invalid simple template id is a compile-time error, unless it names a function template specialization (in which case <DocLink src="cpp/language/sfinae">SFINAE</DocLink> may apply).

```cpp
template<class T, T::type n = 0>
class X;

struct S
{
using type = int;
};

using T1 = X<S, int, int>; // error: too many arguments
using T2 = X<>; // error: no default argument for first template parameter
using T3 = X<1>; // error: value 1 does not match type-parameter
using T4 = X<int>; // error: substitution failure for second template parameter
using T5 = X<S>; // OK
```

<RevisionBlock since="C++20">
When the `template-name` of a simple template id names a constrained non-function template or a constrained template template parameter, but not a member template that is a member of an unknown specialization, and all template arguments in the simple template id are non-dependent, the associated constraints of the constrained template must be satisfied:

```cpp
template<typename T>
concept C1 = sizeof(T) != sizeof(int);

template<C1 T>
struct S1 {};

template<C1 T>
using Ptr = T*;

S1<int>* p; // error: constraints not satisfied
Ptr<int> p; // error: constraints not satisfied

template<typename T>
struct S2 { Ptr<int> x; }; // error, no diagnostic required

template<typename T>
struct S3 { Ptr<T> x; }; // OK, satisfaction is not required

S3<int> x; // error: constraints not satisfied

template<template<C1 T> class X>
struct S4
{
X<int> x; // error, no diagnostic required
};

template<typename T>
concept C2 = sizeof(T) == 1;

template<C2 T> struct S {};

template struct S<char[2]>; // error: constraints not satisfied
template<> struct S<char[2]> {}; // error: constraints not satisfied
```
</RevisionBlock>

If all following conditions are satisfied, two template identifiers are *same*:

- Their `template-name`s or operators refer to the same template
- Their corresponding type template arguments are the same type
- The template parameter values determined by their corresponding constant template arguments are <DocLink src="cpp/language/template_parameters#Template_argument_equivalence">template-argument-equivalent</DocLink>
- Their corresponding template template arguments refer to the same template

Two template identifier that are the same refer to the same<Revision since="C++14"> variable,</Revision> class, or function.

## Templated entity

A *templated entity* (or, in some sources, "temploid") is any entity that is defined<Revision since="C++11"> (or, for a <DocLink src="/cpp/language/lambda">lambda expression</DocLink>, created)</Revision> within a template definition. All of the following are templated entities:

- a class/function<Revision since="C++14">/variable</Revision> template


- <Revision since="C++20">a <DocLink src="cpp/language/constraints">concept</DocLink> </Revision>

- a member of a templated entity (such as a non-template member function of a class template)
- an enumerator of an enumeration that is a templated entity
- any entity defined or created within a templated entity: a local class, a local variable, a friend function, etc

- <Revision since="C++11">the closure type of a <DocLink src="cpp/language/lambda">lambda expression</DocLink> that appears in the declaration of a templated entity</Revision>

For example, in

```cpp
template<typename T>
struct A
{
void f() {}
};
```

the function `A::f` is not a function template, but is still considered to be templated.

A *templated function* is a function template or a function that is templated.

A *templated class* is a class template or a class that is templated.

<Revision since="C++14">A *templated variable* is a variable template or a variable that is templated. </Revision>

## Keywords

<DocLink src="cpp/keyword/template">template</DocLink>,
<DocLink src="cpp/keyword/export">export</DocLink>

## Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

<DRList>
<DR kind="cwg" id={2293} std="C++98">
<Fragment slot="behavior-published">
the rules of determining whether a template identifier is valid were not provided
</Fragment>
<Fragment slot="correct-behavior">
provided
</Fragment>
</DR>
<DR kind="cwg" id={2682} std="C++98">
<Fragment slot="behavior-published">
the definitions of templated function/template class (C++98)/templated variable (C++14) were missing
</Fragment>
<Fragment slot="correct-behavior">
added
</Fragment>
</DR>
<DR kind="cwg" id={2308} std="C++98">
<Fragment slot="behavior-published">
two template identifiers were different if their corresponding constant template arguments are not template-argument-equivalent
</Fragment>
<Fragment slot="correct-behavior">
they are different if their corresponding constant template parameter values are not template-argument-equivalent
</Fragment>
</DR>
</DRList>

## See also

<DocLink src="c/language/generic">C documentation</DocLink> for __Generic selection__