CodeBlanks Logo Icon CodeBlanks

Concept overloading

Learn function overloading with concepts.

What is concept overloading?

Concept overloading is defining the same template function name several times with different concept constraints. At a call site the compiler picks the best overload based on which concept the type satisfies.

Example: a print function can be written separately for integral and floating_point types. template<std::integral T> void print(T v) and template<std::floating_point T> void print(T v). print(3) calls the integral version, print(2.5) calls the floating_point version. Type-based behaviour is then dispatched at compile time.

More specialised concept

In concept overloading, a more specialised concept is preferred over a more general one. std::integral is more general; std::signed_integral is more specialised.

Example: if both std::integral and std::signed_integral versions exist, print(-3) goes to the signed version. Because int is both integral and signed_integral; signed_integral is more specific. The compiler makes this choice with partial ordering. The correct version is then picked without ambiguity.

Practice Write integral and floating_point print

Write two print overloads: first template<std::integral T> void print(T v) with body std::cout << "i:" << v;; second template<std::floating_point T> void print(T v) with body std::cout << "f:" << v;. In main call print(3).

Starter code

main.cpp
#include <iostream>
#include <concepts>

// Write the integral print overload
// Write the floating_point print overload

int main() {
    // Make the first call
    return 0;
}

Sample solution

main.cpp
#include <iostream>
#include <concepts>

template<std::integral T>
void print(T v) {
    std::cout << "i:" << v;
}

template<std::floating_point T>
void print(T v) {
    std::cout << "f:" << v;
}

int main() {
    print(3);
    return 0;
}

Expected output

i:3

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 How is the overload chosen?

  • By which concept the type satisfies Correct answer
  • It is chosen randomly
  • The type is queried at runtime
  • By the order of function definitions

Explanation: The compiler checks which concept the call type satisfies and picks the most specialised version.

2 Match the call to the type

Term Meaning
print(3) int call
print(2.5) double call
print('a') char call
print(3.14f) float call

3 Floating-point constraint

Question
template<____ T> void print(T v) { std::cout << v; }
Answer
template<std::floating_point T> void print(T v) { std::cout << v; }

Explanation: std::floating_point accepts only floating-point types.

All lessons in Advanced