Is it possible that the SFINAE test could fail although the expression value(arg) is valid?
The way you wrote S: yes, it's possible.
It follows a minimal, (not) working example:
#include<type_traits> template< typename T > struct S { template< typename U , typename = std::enable_if_t<std::is_constructible< T, U >::value > > explicit S (U&& arg) : value{arg} {} T value; }; struct A {}; struct B { B(A &) {} }; int main() { S<B> s(A{}); }
The code above doesn't compile, but it does compile if you comment out the following line:
, typename = std::enable_if_t<std::is_constructible< T, U >::value >
The problem is that you are not forwarding the constructor parameter. Instead, you are using an lvalue reference to a variable of type rvalue reference to A (that is arg) as an argument for value.
B is not constructible from an rvalue reference to A and the sfinae expression fails (correctly), but you are not actually using such a reference to construct the parameter, so removing the sfinae expression it works.
In fact, B is constructible from an lvalue reference to A, that is what you are using when you write value{arg}.
You should rather write S as it follows:
#include<utility> // ... template< typename T > struct S { template< typename U , typename = std::enable_if_t<std::is_constructible< T, U >::value > > explicit S (U&& arg) : value (std::forward<U>(arg)) { } T value; };
Note the use of std::forward to actually forward the parameters with the right types.
This at least solves the above mentioned issue and it should give you the guarantees you were looking for.