std :: function中的可变参数模板参数匹配 [英] variadic templates parameter matching in std::function

查看:865
本文介绍了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 a std::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆