【问题标题】:Cannot construct from lambda无法从 lambda 构造
【发布时间】:2018-03-26 10:51:09
【问题描述】:

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

#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 说:

错误:不存在从“lambda [](int, async::Callback)->void”到“async::Function”的合适的用户定义转换

现在如果我替换

    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>&)>;

但是&lt;Res(Args...)&gt; 的特化无法编译...

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • @SimonKraemer 也可以完全删除async::Function 并改用裸std::function...
    猜你喜欢
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多