Reputation: 4663
On some resource I saw a code:
struct C
{
template <typename T, typename = typename enable_if<!is_same<C, typename decay<T>::type>{}>::type>
C(T&& f){}
}
I tried my best but still need some clarification. I know this scary thing is needed for the SFINAE
idiom - if something fails the templated function simply will not be created. Here what I found:
typename decay<T>::type
- this removes cv qualifiers from type T
, or converts an array T
to pointer T
or converts T
to function pointer. But what is this typename
before? I suppose this is related to dependent type, i.e. the supplied type T
is a thing that is a part of another template, right?is_same<A, B>{}
- what is this {}
braces doing here? Why?typename enable_if<A>::type
- as I understood if A
is true the type
field exist and in this case it's void
since only one argument was passed to enable_if
, right? But again - what is this typename
before?template <typename T, typename = typename A>
- what is this typename = typename A
? Where's the argument name at all?!Upvotes: 0
Views: 58
Reputation: 3082
std::decay<T>
, for example) std::is_same
has cast operator to bool, and through {} object of that type is created and then converted to bool (at compile time). Alternative variant is std::is_same<...>::value
std::is_same
returns true, then member type of std::enable_if
is exists and SFINAE can pass through that functionP.S. std::enable_if
looks like that
template<bool B, class T = void> //(1)
struct enable_if {};
template<class T> /(2)
struct enable_if<true, T> { typedef T type; };
So, if the first parameter is false then primary template (1) is selected and it has not type member, but in case when it is true specialization (2) is selected
Upvotes: 2