Wan*_*ang 6 c++ templates variadic-templates std-function c++17
我遇到了一个问题。当我使用类似的东西时,std::function<A(Fs...)>
它不起作用,但std::function<A(Fs..., B)>
确实起作用。这是在 Clang 8.0 下;它在 GCC 下都不起作用。这是示例:
#include <functional>
template<typename A, typename B, typename ...Fs>
void func_tmpl1(std::function<A(Fs..., B)> callable)
{
}
template<typename A, typename ...Fs>
void func_tmpl2(std::function<A(Fs...)> callable)
{
}
class Cls1{};
void func0(std::function<void(float, Cls1)> callable)
{
}
int main()
{
std::function<void(float, Cls1)> f1 = [](float a, Cls1 b){};
func0(f1);
func0([](float a, Cls1 b){});
func_tmpl1<void, Cls1, float>(f1); // fails in GCC
func_tmpl2<void, float, Cls1>(f1);
func_tmpl1<void, Cls1, float>( // fails in GCC
[](float a, Cls1 b)
{
}
);
func_tmpl2<void, float, Cls1>( // fails in both
[](float a, Cls1 b)
{}
);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在Godbolt 上,我们可以看到 GCC 总是失败,但 Clang 只在最后一次函数调用时失败。谁能解释这里发生了什么?
为了方便起见,我们将代码中的三个失败调用称为#1、#2 和#3。
问题是,当显式指定模板参数包对应的模板实参时,模板参数包是否仍然参与模板实参推导,如果参与,推导失败是否会导致整个调用格式错误?
模板参数推导可以扩展与模板参数包对应的模板参数序列,即使该序列包含显式指定的模板参数也是如此。
我们可以推断模板参数推导仍然应该执行。
在 的声明中func_tmpl1
,std::function<A(Fs..., B)>
是一个非推导上下文([temp.deduct.type]/9:“如果 P 的模板参数列表包含不是最后一个模板参数的包扩展,则整个模板参数列表是一个非推导上下文) -推导的上下文。”),因此模板参数推导 forFs
应被忽略,并且 #1 和 #2 都是格式良好的。有一个GCC 错误报告。
对于#3,模板参数推导显然失败了(std::function<A(Fs...)>
相对于 lambda 类型),但是推导失败真的会导致代码格式错误吗?在我看来,标准对此并不清楚,并且存在一个相关问题。从CWG 的回复来看,#3 确实格式不正确。
归档时间: |
|
查看次数: |
105 次 |
最近记录: |