This article has been updated for C++20.
Let’s take a look at the following code sample:
template <typename T>
struct foo
{
foo(T) {}
};
int main()
{
std::pair p{ 1, "one" };
std::vector v{ 1, 2 };
foo f{ 42 };
}
Here, p is a std::pair, v is a std::vector, and f is a foo. But there is no such thing as a std::vector type (nor std::pair or foo). std::vector<int> is a type, and std::vector<T> is a type template, but std::vector is just a placeholder that activates a C++17 feature called class template argument deduction (which we will call CTAD for short).