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, ie 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?! 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 function PS 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.