Conteúdo do Curso
C++ Templates
C++ Templates
Class Template Argument Deduction
You might have already used some of them without realizing they were templates at first, possibly due to Class Template Argument Deduction (CTAD).
With C++17, we can take advantage of Class Template Argument Deduction (CTAD). This feature allows us to create instances of our template classes without explicitly specifying the template types. Instead, the compiler infers the types based on the constructor parameters. Let’s look at some examples using std::pair
.
main
#include <iostream> #include <utility> // for std::pair int main() { std::pair<int, char> my_pair(1, 'a'); std::cout << my_pair.first << " : " << my_pair.second << std::endl; }
Note
Previously, this was the only way to create an instance of
std::pair
. However, now it is possible to omit the<int, char>
part. Try removing it and run the code again.
Class template argument deduction is only performed if no template argument list is present. If a template argument list is specified, deduction does not take place.
main
#include <iostream> #include <utility> // for std::pair int main() { std::pair<> my_pair(1, 'a'); // Error std::cout << my_pair.first << " : " << my_pair.second << std::endl; }
When creating an object with a single argument that matches a specific type of a class template, CTAD prefers to use that type directly, simplifying instantiation for user-defined template classes. For instance, with a template class like Box
, users can instantiate it without specifying type arguments when providing constructor arguments.
main
#include <iostream> template <typename T> class Box { T value; public: Box(T value): value(value) {} }; int main() { // No need to write Box<int> a{1}; Box a{1}; // Deduction: Box<int> Box b{a}; // Deduction: Box<int>, not Box<Box<int>> }
CTAD can make maintaining code easier. If the underlying types change, there’s less code to update, leading to fewer opportunities for errors.
vector
template <typename T> class Vector3D { T x, y, z; public: Vector3D(T x, T y, T z) : x(x), y(y), z(z) {} }; Vector3D vec{1.0, 2.0, 3.0}; // CTAD deduces Vector3D<double>
When using containers or wrappers with specific constructors, CTAD can simplify the code. Suppose you have a custom Matrix
or Vector
class that wraps an underlying data type. Using CTAD here can help ensure that type deduction happens automatically based on the arguments provided, improving readability and flexibility.
Obrigado pelo seu feedback!