C++ 针对std::function的lambda表达式和模板推导:为什么这样做?

C++ 针对std::function的lambda表达式和模板推导:为什么这样做?,c++,lambda,std-function,template-argument-deduction,C++,Lambda,Std Function,Template Argument Deduction,我的问题与这个问题有些关联: . 请阅读此问题及其接受的答案 所以,公认的答案是,下面的代码使针对lambda的模板参数推断成功,但是为什么呢 template<class T> struct Identity{ typedef T type;//why this helps? }; template<typename BaseT> vector<BaseT> findMatches(vector<BaseT> search, ty

我的问题与这个问题有些关联: . 请阅读此问题及其接受的答案

所以,公认的答案是,下面的代码使针对lambda的模板参数推断成功,但是为什么呢

template<class T>
struct Identity{
  typedef T type;//why this helps?
};

template<typename BaseT>
vector<BaseT> findMatches(vector<BaseT> search, 
    typename Identity<function<bool (const BaseT &)>>::type func)
{
    vector<BaseT> tmp;

    for(auto item : search)
    {
        if( func(item) )
        {
            tmp.push_back(item);
        }
    }

    return tmp;
}

void Lambdas()
{
    vector<int> testv = { 1, 2, 3, 4, 5, 6, 7 };

    auto result = findMatches(testv, [] (const int &x) { return x % 2 == 0; });//lambda here.

    for(auto i : result)
    {
        cout << i << endl;
    }
}

int main(int argc, char* argv[])
{

    Lambdas();

    return EXIT_SUCCESS;
}
模板
结构标识{
typedef T type;//这有什么帮助?
};
样板
矢量搜索匹配(矢量搜索,
typename标识::type func)
{
向量tmp;
用于(自动项目:搜索)
{
if(职能(项目))
{
tmp.推回(项目);
}
}
返回tmp;
}
void Lambdas()
{
向量testv={1,2,3,4,5,6,7};
自动结果=findMatches(testv,[](const int&x){return x%2==0;});//此处为lambda。
用于(自动i:结果)
{

cout之所以有效,是因为未推导出
func
参数的类型。 通过使用外部特征类
Idendity
,代码使
func
参数的类型依赖于
BaseT
模板参数,将其转换为非推断上下文

因此,
BaseT
会为
search
参数推导出
func
的类型,事实上,依赖于
BaseT
func
的类型是已知的。最后,您的lambda可以隐式转换为所需的
std::function
类型

如果省略此技巧使
func
的类型依赖于
BaseT
,例如:

template<typename BaseT>
vector<BaseT> findMatches(vector<BaseT> search, 
     function<bool (const BaseT &)> func)
模板
矢量搜索匹配(矢量搜索,
函数(func)
然后,对
func
也进行模板参数推导,并将产生编译器错误

但是下一步是什么呢?在替换之后,
Identity::type
变成了
function
,但是lambda表达式不是那种类型的吗,并且在模板参数推导中不会发生转换(尽管这里是模板参数替换)

您是正确的,在模板参数推导过程中没有子项,但一旦完成,我们将函数调用视为调用实例化函数。 这意味着
Identity::type
已被
function
替换,您正在调用的实例化函数是:

vector<int> findMatches(vector<int> search, function<bool (const int&)> func)
矢量搜索匹配(矢量搜索,函数func)

由于它采用一个具体的
函数
,lambda可用于构造
func

,因此它可以工作,因为在实例化函数模板后,lambda表达式在函数重载阶段(阶段)隐式转换为lambda?所以程序是模板参数扣除->模板参数替换->重载解析(转换发生在哪里?)@基本上是韩晓。记住函数模板不是函数,它是一个如何制作函数的配方。因此,一旦你推导出模板参数,然后你就用实际推导出的类型打印出一个函数。你实际上调用的是这个函数,因为它有一个真正的
functional
类型,lambda可以转换。