Reputation: 2180
Stroustrup C++ 4th Ed Page 796 states that
"If
Enable_if
’s condition evaluates tofalse
, the whole function declaration of which it is part is completely ignored." and "...we don’t declare anything.".
I have also read this suggested thread in which SFINAE only works if substitution in argument deduction of a template argument makes the construct ill-formed.
For this example, I am trying to understand how SFINAE omits the Enable_if<false, T> f0(int x) {};
construct.
Is it because of the lack of a return type ::type
makes the template construct ill-formed language-wise?
#include <type_traits>
using namespace std;
template<bool B, typename T>
using Enable_if = typename std::enable_if<B, T>::type;
struct X
{
template <class T>
Enable_if<false, T> f0(int x) {};
template <class T>
Enable_if<true, T> f0(int x) {};
};
int main(void)
{
X xx;
xx.f0<void>(0);
return 0;
}
I understand the case in the prior mentioned thread for a construct:
template <typename enable_if<false>::type* = nullptr>
void f0() {}
this is because the template parameter is ill-formed (no ::type
to assign nullptr
to.)
Upvotes: 2
Views: 254
Reputation: 32722
I'm trying to understand how SFINAE omits the
Enable_if<false, T> f0(int x) {};
construct. Is it because of the lack of a return type::type
makes the template construct ill-formed language-wise?
Short answer: NO!
You need to have a look, how SFNINAE basically works form a good c++ book. For instance from the cppreference.com
This rule applies during overload resolution of function templates: When substituting the explicitly specified or deduced type for the template parameter fails, the specialization is discarded from the overload set instead of causing a compile error.
Meaning, you need first of all overloaded template-functions! This has been achieved in the given example code.
Secondly, the part of std::enable_if
. It checks the condition you provide in
template< bool B, class T = void >
// ^^^^^^^ -----------------------> here!!
struct enable_if;
at compile-time and, decide whether to activate the part below or not.
The standard library component
std::enable_if
allows for creating a substitution failure in order to enable or disable particular overloads based on a condition evaluated at compile time.
In your code, for the given overload
template <class T>
Enable_if<false, T> f0(int x) {};
// ^^^^^ ---------------> CONDITION == false
the condition is false
, and hence in effect, this part (code) will not be there after the compiler done with the compilation.
Is it because of the lack of a return type
::type
makes the template construct ill-formed language-wise?
For the reason mentioned above, NO; that is not the reason!
By providing a template-type-alias like this
template<bool B, typename T>
using Enable_if = typename std::enable_if<B,T>::type;
// ^^^^^^^ --> type has been mentioned here!
you have mentioned the ::type
via the alias type Enable_if</*condition*/, T>
.
Upvotes: 2