std :: function中的可变参数模板参数匹配 [英] 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));
}
我有2个问题:
1。
我不明白为什么 func< void,double>(f);
这行会给我带来编译错误
1.
I do not understand why does the line func<void, double>(f);
give me a compiling error
/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
(如非注释行)有效。
whereas if I cast the parameter f
to a std::function
(as in the non-commented line) it works.
2。
最令人困惑的问题是,如果我使用 func
的非可变版本(即,只需替换 typename ...
由 typename
表示,因此实际上 func
需要一个 std :: function< ; Return(Params)>
作为参数),然后 main
中的注释行将按需要工作。知道为什么吗?
2.
And the most puzzling issue is that, if I use a non-variadic version of func
(i.e. just replace typename...
by typename
so in effect func
takes a std::function<Return(Params)>
as parameter), then the commented line in main
works as desired. Any ideas why?
推荐答案
我不明白为什么
行func< void,double>(f);
给我一个编译错误
编译器没有知道您想让 Params
精确地 double
,它认为您可能想要推导包含更多元素的包装,例如 double,int,void *,char
或 double,double,double
或其他类型的包,它不知道如何从参数 f
推论得出。
The compiler doesn't know that you want Params
to be exactly double
, it thinks maybe you want it to deduce a pack with more elements, such as double, int, void*, char
or double, double, double
or some other pack of types, and it doesn't know how to deduce that from the argument f
.
理论上,可能还有 std :: function
的其他专业化,可以从 f
构造而来,这将使编译器能够为 Params
推导一包多个类型的包装(不实例化<$ c的一切可能的专业化,这是不正确的$ c> std :: function 并对其进行测试,这是不可行的。
In theory there could be other specializations of std::function
which could be constructible from f
and which would allow the compiler to deduce a pack of more than one type for Params
(it can't know that isn't true without instantiating every possible specialization of std::function
and testing them, which is not feasible.
而如果我将参数 f
转换为 std :: function
(如
whereas if I cast the parameter
f
to astd::function
(as in the non-commented line) it works.
因为现在编译器可以推断 Params
Because now the compiler is able to deduce Params
correctly.
最令人困惑的问题是,如果我使用的是非可变版本的
func
[...],然后根据需要在主作品中的注释行。知道为什么吗?
And the most puzzling issue is that, if I use a non-variadic version of
func
[...] then the commented line in main works as desired. Any ideas why?
因为现在编译器知道 Params
是一个类型,而不是一包零个或多个类型,所以当您说 func< void,double>
时,它知道 Params
是 double
,而不是 double,int,void *,char
或其他一些参数包。
Because now the compiler knows that Params
is a single type, not a pack of zero or more types, so when you say func<void, double>
it knows Params
is double
, and not double, int, void*, char
or some other parameter pack.
编辑以回答您的评论,请考虑以下问题:
Edit in answer to your comment, consider this:
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");
我只为两个参数给出了一个明确的模板参数,因此第三个参数必须仍然是
I've only given an explicit template argument for two of the parameters, so the third must still be deduced.
当您拥有可变参数模板时,可能还需要任意数量个其他参数。
When you have a variadic template there could be any number of other parameters remaining to be deduced.
这篇关于std :: function中的可变参数模板参数匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!