函数中的可变模板参数匹配
variadic templates parameter matching in std::function
我有以下代码:
#include <iostream>
#include <functional>
template<typename Return, typename... Params>
void func(std::function<Return(Params... )> x) {}
void f(double) {}
int main() {
//func<void, double>(f); // compile error here in the variadic case
func(std::function<void(double)>(f));
}
我有两个问题:
1。我不明白为什么func<void, double>(f);
行给我一个编译错误
/Users/vlad/minimal.cpp:10:5: error: no matching function for call to 'func'
func<void, double>(f); // compile error here in the variadic case
^~~~~~~~~~~~~~~~~~
/Users/vlad/minimal.cpp:5:6: note: candidate template ignored: could not match 'function<void (double, type-parameter-0-1...)>' against 'void (*)(double)'
void func(std::function<Return(Params... )> x) {}
^
1 error generated.
然而,如果我将参数f
转换为std::function
(如未注释的行),它可以工作。
2。最令人困惑的问题是,如果我使用func
的非可变版本(即只是用typename
替换typename...
,因此实际上func
将std::function<Return(Params)>
作为参数),那么main
中的注释行就可以按需工作。知道为什么吗?
我不明白为什么
func<void, double>(f);
行给我一个编译错误
编译器不知道你想让Params
恰好是 double
,它认为你可能想让它推断出一个包含更多元素的包,比如double, int, void*, char
或double, double, double
或其他类型的包,它不知道如何从参数f
中推断出这一点。
理论上,std::function
的其他专门化可以从f
构造,这将允许编译器为Params
推断出一个不止一种类型的包(如果没有实例化 std::function
的所有可能的专门化并测试它们,它无法知道这是不是真的,这是不可行的。
然而,如果我将参数
f
强制转换为std::function
(如未注释行),它可以工作。
因为现在编译器能够正确地推导出Params
最令人困惑的问题是,如果我使用
func
的非可变版本[…],那么main中的注释行就能正常工作。知道为什么吗?
因为现在编译器知道Params
是单一类型,而不是0个或多个类型的包,所以当你说func<void, double>
时,它知道Params
是double
,而不是double, int, void*, char
或其他参数包。
编辑回答你的评论,考虑一下:
template<typename T, typename U, typename V>
int func(T t, U u, V v)
{ return 0; }
int i = func<int, char>(1, '2', "three");
我只为其中两个形参给出了显式的模板实参,因此第三个形参仍然必须推导出来。
当你有一个可变的模板时,可以有任意数量的其他待推导的形参
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类