如何从函数模板的实例化中推断出模板参数?

3
我知道如何从类模板的实例推断出模板参数:
template <typename T>
struct foo {};

template <typename T>
struct foo_param;

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

但是对于函数模板,我却不知道如何做到相同的效果。这似乎有些困难。

template <typename T>
void bar() {}

template <auto F>
struct bar_param;

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

执行失败

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

我认为我理解了这个错误(事实上后来证明我并没有理解但那是另一个问题),但我不知道如何避免它。如何从&bar<int>推断出例如int


1
有趣的是,我以前从来没有需要做过这个。这有什么用途呢?我敢打赌总体上说这是不可能的。 - Passer By
@PasserBy 我必须承认我手头没有使用案例。这是由这个问题 https://dev59.com/5loJtIcB2Jgan1znV2IQ 触发的。在我的答案中,我首先写道“您不能使用未命名的模板参数”,然后我意识到它可以被推断出来,然后我意识到我不知道如何在函数模板的情况下推断它。 - 463035818_is_not_a_number
我理解这个错误。 - Jarod42
@Jarod42 说实话,我没理解这个错误 ;). 这只是我的一种方式来表达,“不要太在意它,我需要其他东西”。与此同时,我认为问题在于 &bar<T> 的类型取决于 T(即使实际上并不是这样)。Clang 的错误消息更有意义 https://godbolt.org/z/3YvEx1 - 463035818_is_not_a_number
来自MSVC的错误信息“显式特化使用了部分特化语法,请使用template <>”,并不是很有帮助。我们需要部分特化... - Jarod42
显示剩余6条评论
1个回答

2

我认为你想要的是不可能的。

至少不能通过函数类型来实现,因为对于每种类型,bar<T> 的类型都完全相同:一个没有参数的返回 void 的函数。

你可以使用简单的 static_assert() 进行验证。

static_assert( std::is_same_v<decltype(bar<int>), decltype(bar<long>)> );

我知道我忽略了什么,只是期望它朝相反的方向前进 ;) - 463035818_is_not_a_number
@largest_prime_is_463035818 - 是的... 这是一个有趣的问题。 - max66
指向实例的指针是不同的,因此可以测试特定类型或一组类型,但这相当有限。 - 463035818_is_not_a_number
问题仅在于部分特化,使用完全特化即可解决(https://godbolt.org/z/WWhrs9)。非类型模板参数比类型模板参数有更严格的规则,但我无法找到它在此处违反的规则 :-/ - Jarod42

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接