Recipe
Fix a build that fails inside a template
Use when: the first error: points into a template's body or a library header, and the output runs to pages of required from here, requested here and note: candidate lines
Goal: the one line of your own code that caused the error, and whether to change the type you passed or the call you made
Taught in Reading template errors · extends Fix a build that won't compile
Quick recipe
-
1
Same first move as any build failure: skip to the first line that says
error:and read its message. Ignore the length of the output.Example
In GCC's 374 lines for
print_all(points), the first error is line 3:main.cpp:12:19: error: no match for 'operator<<' (operand types are ... and 'const Point'). Something tried to print aPoint.Why: every template error has one real
error:line; everything else is context or candidates. -
2
Look for the type the template was filled in with. GCC writes
[with T = ...]; Clang writes the type in angle brackets, likeprint_all<Point>.Example
GCC:
In instantiation of 'void print_all(const std::vector<T>&) [with T = Point]'. Clang:in instantiation of function template specialization 'print_all<Point>'. Both sayTisPoint.Why: the template's code is fine for some types. The error is about this particular
T. -
3
Find the line in your file that asked for this template. GCC prints it before the error, ending
required from here. Clang prints it after the error, as a note endingrequested here.Example
GCC:
main.cpp:18:14: required from here. Clang:main.cpp:18:5: note: ... requested here. Line 18 isprint_all(points);, the call inmain.Why: the error line may sit in a header you never wrote. Your line is the one you can change.
-
4
Check whether the template has a concept on it.
Example
Constrained version: Clang's last note is
because 'out << value' would be invalid. The missing requirement is "aPointcan be printed with<<."- the first error is "no matching function" at your own line, followed by
constraints not satisfied— the template is constrained. Read down the chain of notes to the last one (the required expression ... is invalidon GCC,because ... would be invalidon Clang). It names the exact requirement your type is missing. - the first error is inside the template's body — the template is unconstrained. The error line itself is the requirement: the operation the body tried on your
T.
Why: a concept is checked at the call, before the body is written out, so its notes say which requirement failed in plain terms.
- the first error is "no matching function" at your own line, followed by
-
5
Decide which side is wrong. Either give the type what the template needs, or stop passing that type. Then rebuild and start again from Step 1 if anything is left.
Example
Either give
Pointanoperator<<, or don't callprint_allon points. In the second worked example below, the fix is on the type:name()becomesname() const.⚡ Shortcut
Skip the
note: candidatelines unless Steps 1–4 didn't explain the error. They're usually most of the output (53 of them in GCC's 374 lines here), and they only confirm that no existing overload accepts your type.Why: the template states what it needs, so the fix belongs to whichever side broke that agreement.
Common mistakes
- Reading the output top to bottom, starting with the candidate list.
- Editing the library header the error points into, instead of your own call or your own type.
- Assuming GCC and Clang put things in the same order. GCC shows your line before the error, Clang after.
- Stopping at the first note of a constraint chain instead of reading down to the last one.