Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

C++ Module 9

Templates and concepts interview questions

Interview questions on templates and concepts: short warm-ups, then what each harder question tests, the first step of a good answer and its follow-ups.

27 questions: 9 warm-ups and 18 with model answers · Levels: Fresher to staff

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher

    Why does larger(1, 2.5) not compile when larger is declared template <typename T> T larger(T a, T b), and how can you fix the call?

    Answered in the lesson C++ function templates and argument deduction

  2. Fresher

    Why are class templates usually defined entirely in header files?

    Answered in the lesson Class templates and argument deduction (CTAD)

  3. Fresher

    Are RingBuffer<int, 8> and RingBuffer<int, 16> the same type? What follows from your answer?

    Answered in the lesson Non-type and template template parameters

  4. Fresher

    What is the difference between a full and a partial specialisation, and which kinds of templates can have each?

    Answered in the lesson C++ template specialisation and overloading

  5. Fresher

    What do (args + ...), (args && ...) and (args || ...) produce when the pack is empty?

    Answered in the lesson Variadic templates and fold expressions

  6. Fresher

    What is the difference between a requires-clause and a requires-expression?

    Answered in the lesson C++20 concepts and requires-clauses

  7. Fresher

    What does if constexpr do that a plain if does not?

    Answered in the lesson Type traits, if constexpr and reading SFINAE code

  8. Fresher to mid

    Can a constexpr function use std::vector? What is the rule?

    Answered in the lesson Compile-time programming with constexpr

  9. Fresher to mid

    What does extern template class Matrix<double>; tell the compiler?

    Answered in the lesson Templates in practice: build time and binary size

Questions with model answers

What each question tests, the first step of a good answer and the follow-ups to expect.

  1. Fresher to mid

    A teammate's template <typename T> T larger(T a, T b) returns "apple" for larger("pear", "apple") with Apple clang and "pear" with GCC. Explain what is deduced and compared, then change the code so that this call is either correct or rejected at compile time.

    What it tests
    Deduction with array-to-pointer decay, what > means for two pointers, and how overload resolution between a template and a non-template can make a template safe.
    First step
    Write down what T becomes. The literals are const char[5] and const char[6]; a by-value parameter makes both decay to const char*, so > compares two addresses, which the standard leaves unordered for unrelated objects. The result depends on where each compiler stores the literals, not on the words.
    Follow-ups

    From the lesson C++ function templates and argument deduction

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.

    Opening the model answers with your pass…

    Model answers open with any MySmartCoPilot pass.

    • Pro pass · 1 week₹79$2.99
    • 30 days₹179$5.99
    • 1 year₹1,699$45

    One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

    It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  2. Mid to senior

    After a teammate adds one call to a function template from a utility header, the build fails with hundreds of lines that point deep inside the header instead of at their code. How do you find the real cause, and what can the template's author do so that the next mistake gives a short error?

    What it tests
    Reading instantiation chains on two compilers, telling the failing operation from the call that caused it, and making a template's requirements explicit with constraints.
    First step
    Read the first error for the operation that failed, for example a < on two Point objects, then follow the "required from" notes of GCC or the "in instantiation of … requested here" notes of Clang down to the last frame in a file you own. That call, and the type it passes, is what to change.
    Follow-ups

    From the lesson C++ function templates and argument deduction

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  3. Mid to senior

    To cut build times, a colleague moved the members of Matrix<T> into matrix.cpp and added template class Matrix<double>; and template class Matrix<std::string>;. The std::string line does not compile, although Matrix<std::string> worked before, and another file now fails to link with Matrix<float>. Explain both failures and choose a better layout.

    What it tests
    Implicit against explicit instantiation of class template members, where instantiation happens, extern template, and the trade-off between build time and the set of types a template supports.
    First step
    Name the rule behind each failure. Implicit instantiation compiles only the members a program calls, while an explicit instantiation definition compiles every member, so one member that cannot work for std::string now fails. And no file can instantiate Matrix<float> any more: the users see only declarations, and matrix.cpp lists only two types.
    Follow-ups

    From the lesson Class templates and argument deduction (CTAD)

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  4. Mid to senior

    Reading a colleague's change, you find auto copies = std::vector{points.begin(), points.end()}; and std::optional retry{limit};, where limit is already a std::optional<int>. What does each line deduce, which one is a bug, and what rule would you set for class template argument deduction in your team?

    What it tests
    The braced-list and copy-deduction rules of CTAD, how to check a deduced type, and a team rule that keeps CTAD where it helps and out of places where it misleads.
    First step
    Work out the types before judging. Braces make the two iterators the elements of an initializer list, so the first line deduces a vector of iterators, not of points. The second line has one argument that is already a std::optional, so the copy deduction candidate wins and retry is a std::optional<int>, a copy of limit.
    Follow-ups

    From the lesson Class templates and argument deduction (CTAD)

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  5. Mid to senior

    The capacity of a message queue declared RingBuffer<Message, N> must now come from a configuration file read at start-up. Why can't the value from the file be N, and how would you redesign the buffer so that both compile-time and run-time capacities work without writing the logic twice?

    What it tests
    What a constant expression is, what a compile-time size buys, and designing one implementation that serves a fixed and a dynamic capacity, as std::span does with its extent.
    First step
    N is part of the type, and types are fixed when the program is compiled; a number read at start-up does not exist yet. So first say what the compile-time capacity was buying (storage inside the object, no allocation, a size the optimiser knows) and decide which of those the new requirement can give up.
    Follow-ups

    From the lesson Non-type and template template parameters

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  6. Mid to senior

    You want Field<"price", double> so that each field's name is part of its type. Why does template <const char* Name> refuse "price", how does a C++20 FixedString parameter make it work, and what does putting names into types cost?

    What it tests
    The rules for pointer and class-type template arguments, structural types and deduction of FixedString's length, and the compile-time and binary-size costs of values in types.
    First step
    State the rule first: a template argument for a pointer parameter may not point to a string literal object, so the literal is rejected however it is written. A class-type parameter takes the literal as a constructor argument instead, and the class keeps the characters in a public array.
    Follow-ups

    From the lesson Non-type and template template parameters

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  7. Mid to senior

    A logging header declares template <typename T> void log_value(T), then an explicit specialisation template <> void log_value(int*), then template <typename T> void log_value(T*). Calls with an int* never reach the specialisation. Explain what the compiler does, and restructure the code so that it no longer depends on the order of declarations.

    What it tests
    How overload resolution, partial ordering and explicit specialisation interact, and replacing function template specialisation with overloads or with delegation to a class template.
    First step
    Separate the two steps. Overload resolution chooses among primary templates and ordinary functions only: both templates accept an int*, and log_value(T*) is more specialised, so it wins. The specialisation was attached to log_value(T) when it was declared, before the pointer overload existed, so it belongs to the loser.
    Follow-ups

    From the lesson C++ template specialisation and overloading

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  8. Fresher to mid

    You need std::unordered_map<GridPoint, int> for a 500 × 500 grid. Show how you make GridPoint usable as a key, what the standard allows you to add to namespace std for it, and how you would check that your hash spreads the keys well.

    What it tests
    The requirements of unordered containers on keys, the rules for specialising standard library templates, and measuring hash quality with bucket statistics instead of guessing.
    First step
    An unordered map needs two things for its key: equality, which a defaulted operator== gives, and a hash, which it finds as std::hash<GridPoint> unless you pass a hasher type. Specialising std::hash for your own type is allowed; the hash must give equal values for equal points.
    Follow-ups

    From the lesson C++ template specialisation and overloading

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  9. Mid to senior

    A helper run_all(fs...) runs several callables with report(fs()...), passing their results to report. After a compiler upgrade, a colleague sees the callables run in a different order. Can that happen? Rewrite run_all so that the callables always run from left to right and report still receives every result.

    What it tests
    The sequencing rules of function arguments, comma folds and braced lists, and keeping results of different types in order without relying on the compiler.
    First step
    Yes. In report(fs()...), each fs() initialises one parameter of report, and the standard says those initialisations are indeterminately sequenced: any order is allowed and need not stay the same between compilers, targets or optimisation levels. The original code depended on one compiler's habit.
    Follow-ups

    From the lesson Variadic templates and fold expressions

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  10. Mid to senior

    Compare a print_all written with C++11 recursion over a pack and one written with a C++17 fold expression: what each instantiates for a call with five arguments, how each handles no arguments, and what each does to build times and error messages. Which do you choose, and when is recursion still the right tool?

    What it tests
    How pack recursion instantiates one function per step, compiler depth limits, empty-pack behaviour, and when a fold, an expansion or pack indexing replaces recursion.
    First step
    Count instantiations. The recursive version peels one argument per call, so five arguments make five instantiations of different lengths plus a non-template base case; the fold makes one instantiation with all five types. nm on the object file shows six functions against one.
    Follow-ups

    From the lesson Variadic templates and fold expressions

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  11. Mid to senior

    A library has encode(T) constrained by requires std::is_integral_v<T>. A colleague adds a faster overload for unsigned types, constrained by requires std::is_integral_v<T> && std::is_unsigned_v<T>, and now every call with an unsigned int fails as ambiguous. Explain why, and fix it without changing any caller.

    What it tests
    How constrained overloads are ordered, why subsumption sees only constraints that come from the same concept, and designing a small family of concepts.
    First step
    Both overloads are viable for unsigned int and have identical parameter types, so only their constraints can decide. The compiler prefers an overload whose constraints subsume the other's, and it compares atomic constraints by where they were written, not by their text. The two appearances of std::is_integral_v<T> are different atomic constraints, so neither overload subsumes the other.
    Follow-ups

    From the lesson C++20 concepts and requires-clauses

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes
  12. Mid to senior

    You own a generic median(std::vector<T>) used across a large codebase, and reviewers ask you to constrain it. Would you use std::totally_ordered, std::sortable or a concept of your own? Say what each choice costs the callers.

    What it tests
    Stating a template's real requirement, satisfying against modelling a concept, and what a constraint does to callers, overloads and error messages.
    First step
    List what the body needs: it copies the values, orders them and reads the middle element, so it needs copyable elements whose < is a strict weak ordering. Then compare the candidates against that list: std::totally_ordered asks for all six comparisons, std::sortable with its default comparator does too, and a concept of your own can ask for exactly <. None of them can check that the ordering is sound.
    Follow-ups

    From the lesson C++20 concepts and requires-clauses

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  13. Mid to senior

    A C++17 library defines two serialize(T) overloads: one with typename = std::enable_if_t<std::is_integral_v<T>>, one with the same form for floating-point types. The build fails with "redefinition of serialize". Explain the cause, give the C++17 fix, and say what C++20 changes.

    What it tests
    How SFINAE removes candidates, what belongs to a function template's signature, and moving an overload set from enable_if to concepts.
    First step
    Default template arguments are not part of a function template's signature. Both declarations are template <typename T, typename> std::string serialize(T), so the second defines the same template again, and enable_if never gets a chance to remove anything. The condition has to become part of the signature.
    Follow-ups

    From the lesson Type traits, if constexpr and reading SFINAE code

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  14. Fresher to mid

    A to_json(value) template tests std::is_integral_v<T>, then std::is_floating_point_v<T>, then strings, with if constexpr. In production, true is written as 1, char fields appear as numbers, and a const int& member reaches the static_assert(false) at the end. Explain each bug and fix the chain.

    What it tests
    How the standard classifies bool, char and references, the order of if constexpr branches, and testing a type dispatch.
    First step
    Each symptom is a classification question. bool and char are integral types, so they take the integer branch, and a reference type belongs to no arithmetic category at all, so const int& falls through every test to the static_assert. Test std::remove_cvref_t<T>, and order the branches from the most specific type to the most general.
    Follow-ups

    From the lesson Type traits, if constexpr and reading SFINAE code

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  15. Mid to senior

    A colleague moved a 65,536-entry lookup table into a constexpr function in a header. Clang now stops with "constexpr evaluation hit maximum step limit", and with the GCC limit raised the build is minutes slower. The header is included by 300 source files. What are your options, and which do you choose?

    What it tests
    What constant evaluation costs and who pays for it, the compilers' limits and flags, and the alternatives: generated sources, data files and computing at start-up.
    First step
    Measure one translation unit that includes the header, with CPU time and peak memory for each compiler, and multiply by the 300 files, because every translation unit that evaluates the table evaluates it again. Then compare that cost with options that compute the table once per build or once per run.
    Follow-ups

    From the lesson Compile-time programming with constexpr

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes
  16. Mid to senior

    After a refactor, static_assert(crc32("123456789") == 0xCBF43926) fails, so the program no longer builds. Nothing can be printed during constant evaluation. How do you find the bug?

    What it tests
    Debugging code that runs in the compiler: reading what the compilers report, running the same function at run time, checking intermediate values, and knowing the CRC's parameters.
    First step
    Read the values first: for a failed comparison, Clang's note shows both sides ("expression evaluates to") and GCC 16 shows what the comparison reduces to, so you see the wrong checksum itself. Then use the fact that a constexpr function is also an ordinary function: call it at run time in a small test and print the table and the steps.
    Follow-ups

    From the lesson Compile-time programming with constexpr

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  17. Senior to staff

    A service takes 14 minutes to build. Clang's -ftime-trace shows that in 300 source files about 40 % of the front-end time goes to instantiating one JSON library's templates. Plan the fix: what you measure, what you change first, and how you prove it helped.

    What it tests
    Reading build traces across a whole build, the per-file cost of instantiation, and choosing between extern template, hoisting, header hygiene, precompiled headers and modules.
    First step
    Measure the whole build, not one file: collect the traces of all 300 files, add up the time per header and per template, and rank them. Then find the few specialisations that most files instantiate, such as the parser and writer for one string type, because those are what extern template or a precompiled header can remove.
    Follow-ups

    From the lesson Templates in practice: build time and binary size

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes

All C++ interview questions · The C++ track

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.