Using SFINAE to Control Overload Resolution

SFINAE vs Concepts: Which should I use?

I've heard that C++20 Concepts can replace SFINAE. Should I still learn SFINAE?

Illustration representing computer hardware

C++20 Concepts are indeed designed to provide a more straightforward and expressive way to constrain templates compared to SFINAE. However, there are still reasons to understand SFINAE:

  1. Legacy codebases: Many existing C++ codebases use SFINAE extensively, especially those that make heavy use of template metaprogramming. Understanding SFINAE will be necessary to maintain and extend such codebases.
  2. Compiler support: While C++20 is now the current standard, not all compilers fully support all C++20 features yet, including Concepts. If you need to write code for older compilers or for environments with incomplete C++20 support, SFINAE may still be necessary.
  3. Understanding overload resolution: SFINAE is deeply tied to the overload resolution process in C++. Understanding how SFINAE works can deepen your understanding of this fundamental aspect of the language.
  4. Some advanced use cases: While Concepts cover most common use cases for constraining templates, there may still be some advanced scenarios where the flexibility of SFINAE is needed.

That said, if you are working in a C++20 environment and writing new code, Concepts should generally be preferred over SFINAE where possible. They provide a cleaner, more readable way to express requirements on template arguments.

For example, instead of using SFINAE to constrain a template parameter to types that have a Render() member like this:

#include <type_traits>

using std::enable_if_t, std::is_same_v,
  std::declval;
template <typename T, enable_if_t<is_same_v<
  decltype(declval<T>().Render()), void>, int> = 0
>
void Draw(T t) {
  t.Render();
}

With Concepts, you could express this more directly:

#include <concepts>

template <typename T>
concept Renderable = requires(T t) {
  { t.Render() } -> std::same_as<void>;
};

template <Renderable T>
void Draw(T t) {
  t.Render();
}

In summary, while Concepts are the future for constraining templates in C++, SFINAE remains an important technique to understand, especially for working with existing codebases and in environments without full C++20 support.

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