Thursday, August 6, 2020

SFINAE and enable_if

Today, while researching for the upcoming C++17 version of WinLamb, I was rethinking the idea of restricting the allowed types on a template argument. That’s an SFINAE thing, scary to many people – including me sometimes, in my love-hate relationship with advanced C++ stuff.

The thing is that I ended up writing a working piece of code using std::enable_if to restrict a template argument, and I’m quite proud of it.

#include <type_traits>

struct One { int num; };
struct Two { int num; };
struct Tre { int num; };

template<
  typename T,
  typename = std::enable_if_t<
    std::is_same_v<T, One> ||
    std::is_same_v<T, Two>
  >
>
void foo(T& o) { ++o.num; }

int main() {
  One o;
  foo(o);
  return 0;
}

In the code above, One and Two classes will work with foo(), whereas Tre will not compile, despite being exactly like the others.