Most of these questions have nothing to do with SFINAE:
- When a dependent name should be considered a type, it needs to be preceded by
typename
. SinceC
is a template parameter totest()
, clearlyC::foobar
is a dependent name. Even though function declarations require a type in front of each argument, the language requires the use oftypename
to turn the dependent nameC::foobar
into a type. With that,typename C::foobar
is just a type and applying a the type constructor*
to it, produces the corresponding pointer type. int C::*
is an unnamed pointer to data member of typeint
.- Names which are not used can always be left out. This applies to function arguments as well as to the template parameters, i.e., yes, the name after
template
can be omitted if it isn't used. Most of the time it is used in some form, though, in which case it is, obviously, required. - I'd think you can write a test which tests for the presence of multiple aspects but I wouldn't to it: SFINAE is unreadable enough as it is. I'd rather explicit combine the different property tests with normal logical operators.