I am writing a class template which takes an arbitrary function pointer as non-type template argument. I would like to use

```
template <auto F> struct Foo;

```

but my compiler (MSVC 2017.5) does not support `auto` in the template parameter list (even though it supports many C++17 features). So I wrote a hack around this somehow like this:

```
template <typename T>
using Func = void (*)(T);

template <typename TF, TF F> struct Foo;
template <typename T, Func<T> F> 
struct Foo<Func<T>, F> { ... };

#define FOO(func) Foo<decltype(func), func>

```

I implemented a streaming operator (for `QDebug` or any other text stream) like this:

```
template <typename T, Func<T> F>
QDebug &operator <<(QDebug &out, const FOO(F) &foo)
{
    ...
    return out;
}

```

But my main code cannot find the right `operator<<` overload:

```
void func(int) { ... }

...

FOO(&func) foo;
qDebug() << foo; // error

```

Surprisingly, everything works when defining the operator like

```
QDebug &operator <<(QDebug &out, const Foo<Func<T>, F> &foo)
//                                     ^^^^^^^^^^^^^^^

```

It seems that `Func<T>` from this last line and `decltype<F>` from the macro do not give the same type. But I checked this and `std::is_same_v<Func<int>, decltype(&func)>` gives true. I cannot think why using the macro `FOO` gives me any other compile time behavior as when not using it.

---

A minimal working example:

```
#include <iostream>

template <typename T>
using Func = void (*)(T);

template <typename TF, TF F> struct Foo;
template <typename T, Func<T> F> 
struct Foo<Func<T>, F> { };

#define FOO(func) Foo<decltype(func), func>

template <typename T, Func<T> F>
std::ostream &operator <<(std::ostream &out, const FOO(F) &foo)
// std::ostream &operator <<(std::ostream &out, const Foo<Func<T>,F> &foo)
{
    return out;
}

void func(int);

int main(int argc, char **argv)
{
    FOO(&func) foo;
    std::cout << foo << std::endl; // error
}

```