August 10, 2023
https://issues.dlang.org/show_bug.cgi?id=24080

          Issue ID: 24080
           Summary: std.traits.TemplateOf doesn't return void for
                    non-template functions
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: phobos
          Assignee: nobody@puremagic.com
          Reporter: schveiguy@gmail.com

std.traits.TemplateOf resolves to `void` on non-template types. However, it fails to compile on non-template functions:

```d
struct S {}
void foo() {}

pragma(msg, TemplateOf!S); // void
pragma(msg, TemplateOf!foo); // error
```

The reason is because the `TemplateOf` overloads only include a catch-all for types:

```d
alias TemplateOf(T) = void;
```

If we change the parameter to an `alias`, it works for both types and functions.

I believe the reason this wasn't "solved" before might be because of the problem with passing basic types to alias parameters. However, this has been solved since 2.087: https://dlang.org/changelog/2.087.0.html#template_alias_matches_basic_types

In fact, I think we can remove the overload that specifically matches template types as well, and just have two aliases:

```d
alias TemplateOf(alias T : Base!Args, alias Base, Args...) = Base;
alias TemplateOf(alias T) = void;
```

--