When a type is not a type

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).

Read more