Skip to content

Commit 500ab7b

Browse files
author
mikeblome
committed
updated templates topic for type deduction on non-type parameters
1 parent 8ddd7c1 commit 500ab7b

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

docs/cpp/templates-cpp.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Templates (C++)"
3-
ms.date: "11/04/2016"
3+
ms.date: "12/27/2019"
44
f1_keywords: ["template_cpp"]
55
helpviewer_keywords: ["templates, C++", "templates [C++]"]
66
ms.assetid: 90fcc14a-2092-47af-9d2e-dba26d25b872
@@ -74,7 +74,7 @@ vtclass<int> vtinstance2;
7474
vtclass<float, bool> vtinstance3;
7575
```
7676

77-
Any built-in or user-defined type can be used as a type argument. For example, you can use std::vector in the Standard Library to store ints, doubles, strings, MyClass, const MyClass*, MyClass&. The primary restriction when using templates is that a type argument must support any operations that are applied to the type parameters. For example, if we call minimum using MyClass as in this example:
77+
Any built-in or user-defined type can be used as a type argument. For example, you can use [std::vector](../standard-library/vector-class.md) in the Standard Library to store variables of type **int**, **double**, [std::string](../standard-library/basic-string-class.md), `MyClass`, **const** `MyClass`*, `MyClass&`, and so on. The primary restriction when using templates is that a type argument must support any operations that are applied to the type parameters. For example, if we call `minimum` using `MyClass` as in this example:
7878

7979
```cpp
8080
class MyClass
@@ -92,7 +92,7 @@ int main()
9292
}
9393
```
9494

95-
A compiler error will be generated because MyClass does not provide an overload for the < operator.
95+
A compiler error will be generated because `MyClass` does not provide an overload for the **<** operator.
9696

9797
There is no inherent requirement that the type arguments for any particular template all belong to the same object hierarchy, although you can define a template that enforces such a restriction. You can combine object-oriented techniques with templates; for example, you can store a Derived* in a vector\<Base\*>. Note that the arguments must be pointers
9898

@@ -106,11 +106,11 @@ vector<MyClass*> vec;
106106
vec2.push_back(make_shared<MyDerived>());
107107
```
108108
109-
The basic requirements that vector and other standard library containers impose on elements of `T` is that `T` be copy-assignable and copy-constructible.
109+
The basic requirements that `std::vector` and other standard library containers impose on elements of `T` is that `T` be copy-assignable and copy-constructible.
110110
111111
## Non-type parameters
112112
113-
Unlike generic types in other languages such as C# and Java, C++ templates support non-type parameters, also called value parameters. For example, you can provide a constant integral value to specify the length of an array, as with this example that is similar to the std::array class in the Standard Library:
113+
Unlike generic types in other languages such as C# and Java, C++ templates support *non-type parameters*, also called value parameters. For example, you can provide a constant integral value to specify the length of an array, as with this example that is similar to the [std::array](../standard-library/array-class.md) class in the Standard Library:
114114
115115
```cpp
116116
template<typename T, size_t L>
@@ -122,14 +122,26 @@ public:
122122
};
123123
```
124124

125-
Note the syntax in the template declaration. The size_t value is passed in as a template argument at compile time and must be constant or a constexpr expression. You use it like this:
125+
Note the syntax in the template declaration. The `size_t` value is passed in as a template argument at compile time and must be **const** or a **constexpr** expression. You use it like this:
126126

127127
```cpp
128128
MyArray<MyClass*, 10> arr;
129129
```
130130

131131
Other kinds of values including pointers and references can be passed in as non-type parameters. For example, you can pass in a pointer to a function or function object to customize some operation inside the template code.
132132

133+
### Type deduction for non-type template parameters
134+
135+
In Visual Studio 2017 and later, in **/std:c++17** mode the compiler deduces the type of a non-type template argument that is declared with **auto**:
136+
137+
```cpp
138+
template <auto x> constexpr auto constant = x;
139+
140+
auto v1 = constant<5>; // v1 == 5, decltype(v1) is int
141+
auto v2 = constant<true>; // v2 == true, decltype(v2) is bool
142+
auto v3 = constant<'a'>; // v3 == 'a', decltype(v3) is char
143+
```
144+
133145
## <a id="template_parameters"></a> Templates as template parameters
134146

135147
A template can be a template parameter. In this example, MyClass2 has two template parameters: a typename parameter *T* and a template parameter *Arr*:

0 commit comments

Comments
 (0)