Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding SFINAE

As far as I know, SFINAE means substitution failures do not result in compilation errors, but just remove the prototype from the list of possible overloads.

What I do not understand: why is this SFINAE:

template <bool C, typename T = void> struct enable_if{};
template <typename T> struct enable_if<true, T> { typedef T type; };

But this is not?

template <bool C> struct assert;
template <> struct assert<true>{};

From my understanding, the underlying logic is identical here. This question emerged from the comments to this answer.

like image 371
nijansen Avatar asked Jul 24 '13 09:07

nijansen


People also ask

What is meant by SFINAE?

Substitution failure is not an error (SFINAE) refers to a situation in C++ where an invalid substitution of template parameters is not in itself an error. David Vandevoorde first introduced the acronym SFINAE to describe related programming techniques.

Will concepts replace Sfinae?

So the simple answer is YES.

What is Typename C++?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.

How do you call a function template in C++?

Defining a Function Template A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.


1 Answers

In C++98, SFINAE is done with either a return type or a function's dummy argument with default parameter

// SFINAE on return type for functions with fixed arguments (e.g. operator overloading)
template<class T>
typename std::enable_if< std::is_integral<T>::value, void>::type
my_function(T const&);

// SFINAE on dummy argument with default parameter for functions with no return type (e.g. constructors)
template<class T>
void my_function(T const&, std::enable_if< std::is_integral<T>::value, void>::type* = nullptr);

In both cases, substution of T in order to get the nested type type is the essence of SFINAE. In contrast to std::enable_if, your assert template does not have a nested type that can be used in substitution part of SFINAE.

See Jonathan Wakely's excellent ACCU 2013 presentation for more details and also for the C++11 expression SFINAE. Among others (as pointed out by @BartekBanachewicz in the comments) is is now also possible to use SFINAE in function template default arguments

// use C++11 default function arguments, no clutter in function's signature!
template<class T, class dummy = typename std::enable_if< std::is_integral<T>::value, void>::type>
void my_function(T const&);
like image 150
TemplateRex Avatar answered Sep 17 '22 03:09

TemplateRex