The Complex Class and Its Scalar Parts
The word complex names the pattern. A specific complex type is the result of pairing that pattern with one chosen scalar type.
Why Precision Becomes a Design Question
Suppose you are writing a program that needs complex numbers, the kind with a real part and an imaginary part. Those two parts do not have to be stored with the same level of precision. One program might be satisfied with single-precision floating-point values, while another needs the greater precision of double-precision values. The choice depends on what the program is doing, not on what complex numbers are in the abstract.
What do you think happens?
What do you think happens to programs with different precision needs if the library offers only one fixed complex type?
Reveal answer
Every program is forced into the same precision choice, so programs with different needs cannot both be served by that one fixed version.
The source describes this directly: a library that offers only one fixed version of complex numbers would force every program into the same choice. The C++ standard library avoids this by offering complex numbers in a form that can be adapted to the precision the programmer needs.
The question this article answers is how that flexibility is built into the standard library, and what it means for you as a programmer. The short answer is that the standard library's complex type is a template. The rest of the article traces what that means step by step.
Tracing a Scalar Choice Step by Step
Before looking at the rules in detail, follow what happens when a programmer uses the template. Watch which parts are already fixed and which part is still open at each step.
Filling in the template for a precision-sensitive program
A programmer needs complex numbers whose real and imaginary parts are stored as single-precision floating-point values. Trace what the template looks like before and after the scalar choice is made.
- 1State 1: the pattern exists, but the scalar type is open
The template describes how a complex number works in general. It is a pattern, not a finished class, and the type of its scalar parts has not been decided yet. Nothing in the pattern is yet a type you can store a number in.
- 2State 2: the programmer supplies a scalar type
The programmer chooses single-precision floating-point, usually called float, and supplies it to the template. The decision about the scalar type is delegated to the programmer at this point, not made in advance by the library.
- 3State 3: a concrete complex type is produced
The pattern and the chosen scalar type together produce a specific complex number type whose parts are float values. This concrete type is what the program actually uses to store values.
The template became a concrete complex type with float parts only after the scalar type was supplied. The template itself was never the type of the stored value.
The Template as an Open Pattern
A template is a pattern that is written once and then filled in with a specific type when it is used. The pattern describes how a complex number works in general, leaving the type of its scalar parts open until a concrete choice is made.
The standard library's complex is a template in exactly this sense. The source states the central design decision directly: the library's complex is a template, so it supports complex numbers whose parts can have different scalar types. The pattern itself is not a finished class with one fixed set of behaviors.
It is worth being precise about what the template does not decide. It does not fix the scalar type in advance. That decision is delegated to the programmer, who supplies a scalar type when using the template. This is the reason the single name complex can stand for a whole family of related types rather than one type alone.
The word complex names the pattern. A specific complex type is the result of pairing that pattern with one chosen scalar type.
Scalar Types the Template Can Accept
The source names two scalar types that the complex number template can support. The first is the single-precision floating-point number, usually called a float. The second is the double-precision floating-point number, usually called a double. Both are scalar types the programmer can supply as the scalar choice for the template.
The source also says the list is not closed. It uses the phrase etc., which signals that other scalar types can be used in the same way. So float and double are the examples the source gives, not a complete list of every type the template accepts. When you read or write code against the template, the rule to remember is that any suitable scalar type can be supplied, not only the two named explicitly.
float and double are named examples of scalar types. The phrase etc. in the source means other scalar types can be plugged into the template in the same way.
From One Template to Several Concrete Types
The relationship between the template and its scalar types runs in one direction. The template is the shared pattern, and each scalar type is a separate option that can be plugged into it. Each choice yields its own concrete complex type. The diagram below shows the shape of that relationship: one template, several scalar options, and a concrete complex type for each option you choose.
Read the diagram from the top down. The template sits at the top and is never itself the type of a stored value. Each scalar option below it produces a different concrete complex type at the bottom. The complex with float parts and the complex with double parts are two distinct types, even though both come from the same template. The third branch stands for the other scalar types the source's etc. signals.
Mistakes Beginners Make with the Template
Common mistake Treating the template as the type of a stored value
What it looks likeThinking that a variable can be declared with the bare template name and nothing else, with no scalar type supplied.
Why it failsThe source states that the template itself is not the type of a stored value. The pattern leaves the scalar type open until the programmer chooses one.
Do this insteadAlways pair the template with one chosen scalar type, such as float or double, to obtain a concrete complex type.
Common mistake Assuming only float and double are allowed
What it looks likeBelieving that the template works only with the two scalar types the source names explicitly.
Why it failsThe source uses the phrase etc. to signal that the list is not closed and that other scalar types can be used in the same way.
Do this insteadTreat float and double as named examples and recognize that other suitable scalar types can be supplied to the template.
Common mistake Thinking one complex type must serve every precision need
What it looks likeChoosing one precision for all complex numbers in a program because it seems simpler, even when different parts of the program need different precision.
Why it failsThe reason the template exists is that programs can need different precision. A single fixed version would force every program into the same choice.
Do this insteadPick the scalar type that matches the precision each program needs, and recognize that different choices produce different concrete complex types.
Template Versus a Single Fixed Class
It helps to contrast the template design with the alternative the source describes. A library that offers only one fixed version of complex numbers has a single underlying scalar type baked into its definition. The template instead leaves that scalar type open. The diagram below compares the two approaches side by side.
The fixed approach is simpler to describe, but it forces every program into one precision choice. The template approach allows each program to pick the scalar type it needs, at the cost of understanding that the template produces a concrete type only after that choice is made. The source presents the template as the way the C++ standard library addresses the precision problem.
Practicing the Scalar Choice
A program needs complex numbers whose parts can be stored with the greater precision of double-precision floating-point values. Using only the ideas in this article, explain which part of the template the programmer supplies, what the template by itself is not, and what kind of type the program ends up with.
Hints
- Look at the section on tracing a scalar choice: the template stays open until a scalar type is supplied.
- The template itself is not the type of a stored value, so ask which scalar type is being supplied.
- The result is a concrete complex type whose parts are double values.
A colleague says the template is the complex type their program stores values in. Explain in two or three sentences why this is not correct, and name the step that is missing.
Hints
- Think about what the template leaves open.
- Name the scalar type the colleague has not supplied.
Summary of the Template Design
- 1The standard library complex is a template, a pattern that becomes a concrete type only after the programmer supplies a scalar type.
- 2The template leaves the scalar type open, so a single name can stand for a family of related complex types.
- 3The source names float (single-precision) and double (double-precision) as scalar types, and its etc. signals that other scalar types can be used too.
- 4The template itself is never the type of a stored value; choosing a scalar type produces the concrete complex type a program uses.
At a glance
- The standard library complex is a template, a pattern that becomes a concrete type only after the programmer supplies a scalar type.
- A single fixed complex class would force every program into the same precision choice, which the template design avoids.
- The source names float (single-precision) and double (double-precision) as scalar types, and its etc. signals that other scalar types can be used in the same way.
- The template itself is never the type of a stored value; choosing a scalar type produces the specific complex type a program actually uses.