`sfinae` proposal... useful or unnecessary? I am trying to learn what SFINAE is. I believe I understand it quite well; however, I do not have a lot of practice in the subject. I mean I would find it difficult to list all the cases in which SFINAE should or could be used, or it would be difficult for me to immediately understand what a given sample of an SFINAE code should do. However, I believe I understand the core concept well enough to use it effectively.

Nonetheless looking through examples of SFINAE usage I came to the few conclusions.

One of which is: it is extremely pointless to use a chain of std::enable_if_t, std::void_t, std::is_same, etc, etc, etc, to define a single type using type = int *. IMHO (of a "newbie" with untrained eyes) such chains make the code less (extremely less) readable. 

The second conclusion was: wouldn't it be useful to have the ability to check few conditions at the same time?

So I created this alias: (well "created" is waaay too big word... I just wrote 4 lines of code...)

template&lt;typename T, typename ...&gt;
using sfinae = T;

template&lt;typename T, typename ...&gt;
using SFINAE = T;


Usage examples

// 1) within class declaration:
template &lt;typename T, 
    sfinae&lt;bool,
        std::enable_if_t&lt;std::is_integral_v&lt;T&gt;&gt;,
        std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;&gt;
    &gt; = true /* provide default option, bc reasons */&gt;
class foo;

// 2) within function declaration:
template &lt;typename T, 
    sfinae&lt;bool,
        std::enable_if_t&lt;std::is_integral_v&lt;T&gt;&gt;,
        std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;&gt;
    &gt; = true /* provide default option, bc reasons */&gt;
void foo;

// 3) as a function return type:
template &lt;typename T&gt; 
sfinae&lt;T,
    std::enable_if_t&lt;std::is_integral_v&lt;T&gt;&gt;,
    std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;&gt;
&gt; const &amp; foo(T const &amp; val);

// 4) To define other SFINAE-conditions as aliases:
template &lt;typename T&gt; 
using check_xyz = sfinae&lt;void,
    std::enable_if_t&lt;std::is_integral_v&lt;T&gt;&gt;,
    std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;&gt;
&gt;;

template &lt;typename T, typename = check_xyz&lt;T&gt;&gt;
class foo;


And my main concern/question is: would a professional c++ developer deem sfinae&lt;/*...*/&gt; (as I proposed it) useful or extremely unnecessary? Are there any changes that could be introduced to the idea?
I just wrote four lines of code...

template&lt;typename T, typename ...&gt;
using sfinae = T;

template&lt;typename T, typename ...&gt;
using SFINAE = T;



You should have written just two lines of code — either the first two or the last two. Not both. "There's more than one way to [spell] it" is the Perl way, not the C++ way. ;) (At least not intentionally! Not intentionally pre-C++2a! Now we're getting both std::filesystem and std::fs, that's a less airtight position.)



As you show, your thing can be used for

template&lt;class T, 
    sfinae&lt;bool,
        std::enable_if_t&lt;std::is_integral_v&lt;T&gt;&gt;,
        std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;&gt;
    &gt; = true&gt;
void foo();


However, this is pretty verbose; surely we'd rather write std::enable_if_t&lt;std::is_integral_v&lt;T&gt; &amp;&amp; std::is_arithmetic_v&lt;T&gt;&gt; than std::enable_if_t&lt;std::is_integral_v&lt;T&gt;&gt;, std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;&gt;. 

So personally I have a different alias that accomplishes the same goal: bool_if_t.

template&lt;bool B&gt;
using bool_if_t = std::enable_if_t&lt;B, bool&gt;;

template&lt;class T, 
    bool_if_t&lt;
        std::is_integral_v&lt;T&gt; &amp;&amp;
        std::is_arithmetic_v&lt;T&gt;
    &gt; = true&gt;
void foo();


This has the advantage that the inner expression is written using normal C++ syntax rules. We don't have to remember some arbitrary rule like "x, y means both x and y must be true"; we just write x &amp;&amp; y. And if we want to enable this function when either x or y is true, we don't have to invent a new primitive; we just write bool_if_t&lt;x || y&gt;. bool_if_t is much more composable than your sfinae&lt;Ts...&gt;, because bool_if_t can exploit the existing expression syntax of C++.



Recommended viewing: "A Soupçon of SFINAE" (Arthur O'Dwyer, CppCon 2017). (Yes, that's me.)

You picked examples that don't really show off the power of sfinae, by the way.
Consider this example:

// 3) as a function return type:
template &lt;typename T&gt; 
sfinae&lt;T,
    std::enable_if_t&lt;std::is_integral_v&lt;T&gt;&gt;,
    std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;&gt;
&gt; const &amp; foo(T const &amp; val);


You take a "value-space" boolean (is_integral_v&lt;T&gt;), lift it up into "SFINAE-space" with enable_if_t, and then apply a logical AND operation in SFINAE-space using your sfinae alias.

template &lt;typename T&gt; 
std::enable_if_t&lt;
    std::is_integral_v&lt;T&gt; &amp;&amp;
    std::is_arithmetic_v&lt;T&gt;, T
&gt; const &amp; foo2(T const &amp; val);


Here I take the same "value-space" boolean, perform the logical AND in value space where we have a dedicated operator &amp;&amp; for maximum expressiveness; and I lift it up into SFINAE-space after doing the AND. This is clearer and also probably more efficient in terms of compile time.

Where your version helps is when your values start in SFINAE-space!

template&lt;class T&gt; 
sfinae&lt;T,
    decltype(std::declval&lt;T&gt;() + std::declval&lt;T&gt;()),
    T*,
    T&amp;
&gt; const &amp; foo3(T const &amp; val);


If we were trying to replicate this code's behavior with the standard tools, we'd say something like

template&lt;class, class=void&gt; struct has_plus : std::false_type {};
template&lt;class T&gt; struct has_plus&lt;T, decltype(void(std::declval&lt;T&gt;() + std::declval&lt;T&gt;()))&gt; : std::true_type {};
template&lt;class T&gt; inline constexpr bool has_plus_v = has_plus&lt;T&gt;::value;

template&lt;class T&gt; 
std::enable_if_t&lt;
    has_plus_v&lt;T&gt; &amp;&amp;
    not std::is_reference_v&lt;T&gt; &amp;&amp;
    not std::is_void_v&lt;T&gt;, T
&gt; const &amp; foo4(T const &amp; val);


That is, we start with a value in SFINAE-space (decltype(std::declval&lt;T&gt;() + std::declval&lt;T&gt;())), lift it into value-space (has_plus_v&lt;T&gt;), do the logical AND in value-space, and lift the result back into SFINAE-space.

Whereas with your foo3, you start in SFINAE-space, do the logical AND via sfinae&lt;...&gt; without leaving SFINAE-space, and then you're done. Much simpler! But harder to read, I think.



A simple way to improve readability is to pick a good name. sfinae_space_and&lt;Ts...&gt; might be clearer. Can you think of a way to write sfinae_space_or&lt;Ts...&gt;? How about sfinae_space_not&lt;T&gt;? Does it make sense, maintainability-wise, to provide one without the others?