Using SFINAE to Control Overload Resolution

Interaction between SFINAE and Overloaded Functions

How does SFINAE interact with normal overloaded functions?

Illustration representing computer hardware

SFINAE interacts with normal function overloading through the overload resolution process. When you call a function, the compiler considers both normal functions and function templates (instantiated with the deduced template arguments) as candidates.

If a function template contains code that would be ill-formed after substituting the deduced arguments, and this code is in a part of the template that undergoes substitution (i.e., the template parameter list, function parameter list, or return type), then a substitution failure occurs. This removes the template from the set of viable candidates, but is not an error.

Consider this example:

#include <iostream>
#include <type_traits>

struct A {
  void foo() { std::cout << "A::foo()\n"; }
};

struct B {
  void bar() { std::cout << "B::bar()\n"; }
};

template <typename T>
auto call_foo(T t) -> decltype(t.foo()) {
  t.foo();
}

void call_foo(B b) {
  std::cout << "Non-template call_foo(B)\n";
  b.bar();
}

int main() {
  A a;

  // Calls the template, A::foo() is valid
  call_foo(a);

  B b;

  // Calls the non-template, B::foo() is invalid
  call_foo(b);
}
A::foo()
Non-template call_foo(B)
B::bar()

When call_foo(a) is encountered, the template is instantiated with T = A. Since A::foo() is valid, the template is viable and is selected, because it's more specialized than the non-template function.

When call_foo(b) is encountered, the template is instantiated with T = B. This leads to a substitution failure because B does not have a foo() member. However, this is not an error. The template is simply discarded from the overload set, and the non-template call_foo(B) is selected instead.

This demonstrates how SFINAE allows templates to be conditionally removed from overload resolution based on the validity of their instantiation, while still allowing normal overloaded functions to be considered.

This Question is from the Lesson:

Using SFINAE to Control Overload Resolution

Learn how SFINAE allows templates to remove themselves from overload resolution based on their arguments, and apply it in practical examples.

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Using SFINAE to Control Overload Resolution

Learn how SFINAE allows templates to remove themselves from overload resolution based on their arguments, and apply it in practical examples.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved