Given:
template <typename T1>
struct Foo {};
and:
template <typename T2>
void bar(const T2&) {}
I'd like to add a static assertion into bar to ensure that it will only work when T2 is Foo<T1>.
I realise that I could do it like this:
template <typename T1>
void bar(const Foo<T1>&) {}
However, in reality Foo's template parameter list is a little longer, and even if just for "logic" reasons I'd really prefer to avoid writing it out again where bar is defined.
How easy would it be to create a trait for this?
template <typename T2>
void bar(const T2&)
{
   static_assert(is_specialisation_of_v<Foo, T2>, "Only valid for kinds of Foo!");
}
I'm finding it difficult to spell a definition for such a trait.
int main()
{
    Foo<int> f;
    bar(f);      // OK
    char c;
    bar(c);      // Should assert
}
I suppose the common school of thought is that the resulting error should come from incompatible use within bar itself, but I prefer more explicit constraints.