Oh my God, there are so many things here, and it's easy to get confused.
The essence lies in this phrase:
func(Check<int Fallback::*, &U::find>*)
- we want to create a function that accepts a pointer to the Check structure;
- Check is created as a template, which should contain the find variable - U::find;
- for std::vector can create such a Check, so this function is acceptable - func(Check<int Fallback::*, &U::find>*);
- for std::set, such a Check cannot be created, because in std::set there is a method named find (std::set::find) and this is an ambiguity, so only a func(...) call will be created.
And here it is better to write like this: sizeof(func<Derived>(nullptr). It's clearer.