无法从lambda

时间:2018-03-26 10:51:10

标签: c++ c++11 templates lambda

我遇到了编译问题。我不明白为什么以下代码无法编译:

#include <functional>

namespace async {

template<class ...T>
using Callback = std::function<void(const std::string& result, T ...args)>;

template<class Signature>
class Function;

template<class Res, class ...Args>
class Function<Res(Args...)>
{
    std::function<void(Args ...args, const Callback<Res>&)> m_function;
public:
    Function(std::function<void(Args ...args, const Callback<Res>&)>&& function) : m_function(std::move(function)) {}
    Function& operator=(std::function<void(Args ...args, const Callback<Res>&)>&& function) {m_function = std::move(function); return *this;}
    void operator()(Args... args, const Callback<Res>& callback) const {m_function(args..., callback);}
};

}

async::Function<int(int)> getF()
{
    return [](int i, const async::Callback<int> callback)
    {
        callback("", i);
    };
}

int main(int argc, char** argv)
{
    auto f0 = getF();
    return 0;
}

gcc说:

  

在函数'async :: Function getF()'中:   错误:无法将'getF():: __ lambda0 {}'从'getF():: __ lambda0'转换为'async :: Function'

icc说:

  

错误:没有合适的用户定义转换来自&#34; lambda [](int,async :: Callback) - &gt; void&#34; to&#34; async :: Function&#34;存在

现在如果我替换

    return [](int i, const async::Callback<int> callback)
    {
        callback("", i);
    };

通过

    return async::Function<int(int)>([](int i, const async::Callback<int> callback)
    {
        callback("", i);
    });

然后它有效。 为什么我需要明确地演绎以及如何避免这种情况?

更简单的解决方案是用

之类的东西替换类Function
template<class Signature>
using Function = std::nullptr_t;

template<class Res, class ...Args>
using Function<Res(Args...)> = std::function<void(Args ...args, const Callback<Res>&)>;

但是<Res(Args...)>的专业化不能编译......

1 个答案:

答案 0 :(得分:7)

没有Function构造函数接受lambda。有一个接受std::function,并且还有一个接受lambda的std::function构造函数,但C ++永远不会为你组合两个隐式的用户定义转换。

定义所需构造函数的最简单方法是

template <class T>
Function (T&& t) : m_function(std::forward<T>(t)) {}