调用带有std :: function作为lambda参数的函数

Jul*_*anH 6 c++ c++11

我从这里获得的问题的依据是: 无法从lambda函数推断出模板参数std :: function 。此线程中的问题是:为什么此代码无法将lambda传递给函数:

#include <iostream>
#include <functional>

template <typename T>
void call(std::function<void(T)> f, T v)
{
    f(v);
}

int main(int argc, char const *argv[])
{
    auto foo = [](int i) {
        std::cout << i << std::endl;
    };
    call(foo, 1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该线程的答案是,因为lambda不是a std::function。但是为什么这段代码会编译:

#include <iostream>
#include <functional>

template <typename T>
void call(std::function<void(T)> f, T v)
{
    f(v);
}

int main(int argc, char const *argv[])
{
    auto foo = [](int i) {
        std::cout << i << std::endl;
    };
    call({foo}, 1); // changed foo to {foo}
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 5

如链接答案中所述,第一个版本无法编译,因为第一个参数的模板参数推导失败。一个lambda永远不会std::function<void(T)>

第二个版本的编译,因为,写作{foo}std::function<void(T)>变成非推测语境。因此,对于第一个参数,推论不再会失败,因为甚至没有尝试过。因此Tint仅从第二个参数推导得出,并且调用成功,因为lambda可转换为std::function<void(int)>

从[temp.deduct.type]:

非推论上下文是:

  • ...
  • 函数参数,其关联的参数是初始值设定项列表,但参数不具有为其指定从初始值设定项列表中推论的类型。