3

I know how to infer the template parameter from an instantiation of a class template:

template <typename T>
struct foo {};

template <typename T>
struct foo_param;

template <typename T>
struct foo_param< foo<T> > {
    using type = T;
};

But I am lost at doing the same for a function template. The naive

template <typename T>
void bar() {}

template <auto F>
struct bar_param;

template <typename T>
struct bar_param< &bar<T> > {
    using type = T;
};

fails with

<source>:21:19: error: template argument '& bar<T>' involves template parameter(s)
   21 | struct bar_param< &bar<T> > {
      |                   ^~~~~~~

I think I do understand the error (actually it turned out that I didn't but thats a case for a different question), but I don't know how to avoid it. How can I infer eg int given a &bar<int> ?

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    Interestingly, I've never needed to do this ever before. What's the purpose? I would wager it's impossible in general though. – Passer By Dec 29 '20 at 17:22
  • @PasserBy I have to admit I don't have a use-case at hand. It was triggered by this question https://stackoverflow.com/q/65491395/4117728. In my answer I first wrote "you cannot use the unnamed template parameter", then I realized that it can be infered, then I realized that I don't know how to infer it in case of a function template – 463035818_is_not_an_ai Dec 29 '20 at 17:25
  • *"I do understand the error"*, Not me ;-) – Jarod42 Dec 29 '20 at 23:07
  • Notice that gcc rejects wrongly example from [temp.class.spec#match-3](https://timsong-cpp.github.io/cppwp/n4618/temp.class.spec#match-3) with same error message [Demo](https://godbolt.org/z/eeezhq). – Jarod42 Dec 29 '20 at 23:15
  • @Jarod42 to be honest I didnt understand the error ;). It was my way of saying, "don't pay too much attention to it, I need something else". In the mean time I think the problem is that `&bar`s type depends on `T` (even when actually it does not). Clangs error message is much more meaningful https://godbolt.org/z/3YvEx1 – 463035818_is_not_an_ai Dec 30 '20 at 11:00
  • Error from msvc *"explicit specialization is using partial specialization syntax, use template <> instead"* is not helpful neither. We want partial specialization... – Jarod42 Dec 30 '20 at 11:32
  • As I comment in answer, with full specialization, it [works](https://godbolt.org/z/WWhrs9). I think issue is that from function pointer value, we can't know if it is coming from `bar` and neither deduce `T`. – Jarod42 Dec 30 '20 at 11:39
  • @Jarod42 fwiw this fails with same error and it is more intuitive why it cannot work https://godbolt.org/z/qanr9z – 463035818_is_not_an_ai Dec 30 '20 at 12:02
  • Issue, is that gcc rejects valid code with same error. So harder to rely on compiler we know is partially bugged about that kind of code. – Jarod42 Dec 30 '20 at 12:21
  • @Jarod42 right, but the others reject with their respective same error, was my mistake to pick gcc for the link. Maybe I'll write a language lawyer question later, already getting warnings too much discussion in comments ;) – 463035818_is_not_an_ai Dec 30 '20 at 12:25
  • In `g::value`, `T` is clearly non deducible. for `&bar`, it *"seems"* deducible, but I think it is not neither (didn't succeed to find that information though). – Jarod42 Dec 30 '20 at 12:34

1 Answers1

2

I don't think it's possible what do you want.

Not passing through the type of the function, at least, because the type of bar<T> is exactly the same for every type: a returning void function with no-argumens.

You can verify this with a simple static_assert()

static_assert( std::is_same_v<decltype(bar<int>), decltype(bar<long>)> );
max66
  • 65,235
  • 10
  • 71
  • 111
  • I knew I was overlooking something, just expected it to go in the opposite direction ;) – 463035818_is_not_an_ai Dec 29 '20 at 17:38
  • @largest_prime_is_463035818 - yes... is an intriguing question. – max66 Dec 29 '20 at 17:39
  • pointers to instantiations are different, so testing for a specific type or a set of types can be done, but thats rather limited – 463035818_is_not_an_ai Dec 29 '20 at 17:57
  • Issue is "just" the partial specialization, with full specialization, [it works](https://godbolt.org/z/WWhrs9). Non-type template parameters have stricter rules than type template parameters, but I fail to find the one it violates here :-/ – Jarod42 Dec 29 '20 at 22:59