### New presentation slides for template specialization and concepts added

parent a8748828
 --- class: center, middle # Constraints and concepts --- # Constraints and concepts - Not all algorithms can be specialized with types - Sometimes we need type *categories*, type *properties*, or type *concepts* ## Example - Euclidean distance ```c++ template double distance (Point const& a, Point const& b) { double result = 0.0; for (std::size_t i = 0; i < a.size(); ++i) result += (a[i] - b[i]) * (a[i] - b[i]); return std::sqrt(result); } ``` ### Requirements - `Point` must be array-like, i.e., `operator[](int)` and `size()` function - value type of `Point` should be (convertible to) `double` --- # Constraints and concepts - **SFINAE trick:** Introduce a substitution failure for types that are not supported - Can be done inside a `decltype(...)` trailing return-type: ## Example - Euclidean distance ```c++ template auto distance (Point const& a, Point const& b) -> decltype((std::size_t(a.size()), double(a))) // comma separated list of expression { // last expression determines type double result = 0.0; for (std::size_t i = 0; i < a.size(); ++i) result += (a[i] - b[i]) * (a[i] - b[i]); return std::sqrt(result); } ``` --- # Constraints and concepts - **SFINAE trick:** Introduce a substitution failure for types that are not supported - Can be done inside a `decltype(...)` trailing return-type: ## Example - Euclidean distance ``` error: no matching function for call to ‘distance(double, double)’ 23 | distance(1.0,2.0); | ^ specialization.cc:5:6: note: candidate: ‘template decltype (((std::size_t)(a.size()), (double)(a))) distance(const Point&, const Point&)’ 5 | auto distance (Point const& a, Point const& b) -> decltype((std::size_t(a.size()), double(a))) { | ^~~~~~~~ specialization.cc:5:6: note: template argument deduction/substitution failed: specialization.cc: In substitution of ‘template decltype (((std::size_t)(a.size()), (double)(a))) distance(const Point&, const Point&) [with Point = double]’: specialization.cc:23:19: required from here specialization.cc:5:75: error: request for member ‘size’ in ‘a’, which is of non-class type ‘const double’ 5 | auto distance (Point const& a, Point const& b) -> decltype((std::size_t(a.size()), double(a))) { | ~~^~~~ specialization.cc:5:92: error: subscripted value is neither array nor pointer 5 | auto distance (Point const& a, Point const& b) -> decltype((std::size_t(a.size()), double(a))) { | ~^ ``` --- # Constraints and concepts ## Definitions - Class templates, function templates, and non-template functions (typically members of class templates) may be associated with a **constraint**, which specifies the requirements on template arguments, which can be used to select the most appropriate function overloads and template specializations. - A **concept** is a named set of requirements consisting of valid expressions, associated types, invariants, and complexity guarantees. - Each concept is a predicate, evaluated at compile time, and becomes a part of the interface of a template where it is used as a constraint. - A type that satisfies the requirements is said to **model** the concept, or be a model of the concept. - A concept can extend the requirements of another concept, which is called **refinement**. --- # Constraints and concepts ## Valid Expressions C++ expressions which must compile successfully for the objects involved in the expression to be considered models of the concept, e.g., .font-md[
NameExpressionPre-Cond. SemanticsPost-cond.
Size a.size() Returns the size of the container, that is, its number of elements. a.size() >= 0 && a.size() <= MAX SIZE
Element access a[n] 0 <= n < a.size() Returns the nth element from the beginning of the container.
] --- # Constraints and concepts ## Associated Types Types that are related to the modelling type in that they participate in one or more of the valid expressions. Typically associated types can be accessed either through `using` or `typedef` nested within a class definition for the modelling type, or they are accessed through a *traits class*, e.g., .font-md[
NameExpressionSemantics
Value type X::value_type The type of the object stored in a container. The value type must be Assignable, but need not be DefaultConstructible.
] --- # Constraints and concepts ## Invariants Run-time characteristics of the objects that must always be true, that is, the functions involving the objects must preserve these characteristics. The invariants often take the form of pre-conditions and post-conditions, e.g. a class that implements a monoid operation must satisfy: .font-md[
NameSemantics
Associativity For any x, y, and z, f(x, f(y, z)) and f(f(x, y), z) return the same value.
] --- # Constraints and concepts ## Complexity Guarantees Maximum limits on how long the execution of one of the valid expressions will take, or how much of various resources its computation will use, e.g., .font-md[
Semantics
The run-time complexity of element access is amortized constant time.