如何扩展std::function中的函数模板参数包作为函数的参数?

问题描述 投票:0回答:1

这个问题是十年前的另一个问题的延伸:

#include<functional>
template <typename ReturnType, typename... ArgumentTypes>
struct Caller
{
    static void Call(std::function<ReturnType(ArgumentTypes...)>);
};
template <typename ReturnType, typename...ArgumentTypes>
void Call(std::function<ReturnType(ArgumentTypes...)>f);
int main()
{
    Caller<void>::Call([]() {});//Well-formed
    Call<void>({[]() {}});//Well-formed
    Call<void>([]() {});//Ill-formed
}

代码在

std::function
签名中提供了三种方法来扩展模板参数包。前两个已经过测试,格式良好并且可以编译;最后一个问题与旧问题相同,因此格式不正确。问题是,前两种方法是如何绕过原问题和最后一种方法中导致编译失败的问题的呢?

c++ std-function template-argument-deduction function-templates
1个回答
0
投票

对于 struct

Caller
,所有模板参数都会被传递(仅
void
和空包),因为没有部分 CTAD。 Lambda可以转换成
std::function<void()>
,所以就可以了

对于函数模板

Call
,只要参数只是第一个,仍然可能会发生推论。

lambda 不是

std::function
,因此不能推导为
std::function<Ret(Args...)>
,因此第三种方法失败。

对于第二个,额外的

{..}
(没有类型)“强制”构造一个
std::function
,从
std::function{[](){}}
开始,由于
std::function<void()>
CTAD推导为
std::function
。 那么
Call
可以将模板参数推导出为
void
和空包。

© www.soinside.com 2019 - 2024. All rights reserved.