具有std :: function的模板类型推导 [英] Template type deduction with std::function

查看:133
本文介绍了具有std :: function的模板类型推导的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现使用 std :: function 和类型推断的以下行为,这对我来说是意外的:

  #include< functional> 

模板< typename T>
void stdfunc_test(std :: function< T(T)> func){};

int test_func(int arg)
{
return arg + 2;
}

int main()
{
stdfunc_test([](int _){return _ + 2;});
stdfunc_test(test_func);
}

main中的两行结果错误:


没有函数模板 stdfunc_test的实例与参数列表匹配




在Visual Studio 2015中尝试编译时。



为什么类型归纳不能从函数类型中扣除模板类型,并且有解决方法吗?

解决方案

在模板参数推导过程中不执行任何隐式转换,除了: temp.deduct.call



<通常,推论过程会尝试查找使推论的A与A相同的模板参数值(在如上所述对类型A进行转换之后)。但是,在以下三种情况下可能会有所不同:




  • 如果原始P是引用类型,则推导的A(即类型

  • 转换后的A可以是另一个指针或指向成员类型的指针,该成员类型可以通过a转换为推导的A。函数指针转换([conv.fctptr])和/或资格转换([conv.qual])。

  • 如果P是一个类,并且P的形式为simple-template-id,则转换后的A可以是推导A的派生类。同样,如果P是指向形式为simple-template-id的类的指针,则转换后的A可以是指向推导A所指向的派生类的指针。 。


但是,如果template参数不参与模板参数推导,则隐式转换将执行:( temp.ar g.explicit


隐式转换(Clause [conv])将在函数参数上执行,以将其转换为如果参数类型不包含参与模板参数推导的模板参数,则为相应功能参数的类型。 [注意:如果模板参数被明确指定,则不参与模板参数的推导。


因此,如果您明确指定模板参数,它应该可以正常工作:

  stdfunc_test< int>([[](int _){return _ + 2;}); 
stdfunc_test< int>(test_func);


I have discovered the following behaviour with std::function and type deduction, which was unexpected for me:

#include <functional>

template <typename T>
void stdfunc_test(std::function<T(T)> func) {};

int test_func(int arg)
{
    return arg + 2;
}

int main()
{
    stdfunc_test([](int _) {return _ + 2;});
    stdfunc_test(test_func);
}

Both lines in main result in error:

no instance of function template "stdfunc_test" matches the argument list

When attempting to compile in Visual Studio 2015.

Why doesn't the type deduction deduct template type from the function type, and is there a workaround for it?

解决方案

No implicit conversion is performed during template argument deduction, except: temp.deduct.call

In general, the deduction process attempts to find template argument values that will make the deduced A identical to A (after the type A is transformed as described above). However, there are three cases that allow a difference:

  • If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be more cv-qualified than the transformed A.
  • The transformed A can be another pointer or pointer to member type that can be converted to the deduced A via a function pointer conversion ([conv.fctptr]) and/or qualification conversion ([conv.qual]).
  • If P is a class and P has the form simple-template-id, then the transformed A can be a derived class of the deduced A. Likewise, if P is a pointer to a class of the form simple-template-id, the transformed A can be a pointer to a derived class pointed to by the deduced A.

However, if the template parameter doesn't participate in template argument deduction, implicit conversion will be performed: (temp.arg.explicit)

Implicit conversions (Clause [conv]) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction. [ Note: Template parameters do not participate in template argument deduction if they are explicitly specified.

So, if you explicitly specify the template argument, it should work:

stdfunc_test<int>([](int _) {return _ + 2;});
stdfunc_test<int>(test_func);

这篇关于具有std :: function的模板类型推导的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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