微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

重新分配 lambda 时,为什么称为删除的副本分配而不是移动分配?

如何解决重新分配 lambda 时,为什么称为删除的副本分配而不是移动分配?

我正在实现某种嵌套的平面 for_each(人为的例子):

template <class InputIt,class UnaryFunction>
UnaryFunction flat_nested_for_each_of_sorts(InputIt first,InputIt last,UnaryFunction f) {
    while (first != last) {
        f = std::for_each(begin(*first),end(*first),std::move(f));
    }
    return f;
}

我想返回 f,因为它可能是一个包含一些数据的结构体。但我希望这个函数也能与 lambda 一起使用。例如,

int example1() {
    int acc = 0;
    std::vector<std::vector<int>> values{{1,2},{3,4}};
    auto l = [&acc](int i) {acc += i;};
    l = flat_nested_for_each_of_sorts(begin(values),end(values),std::move(l));
    return acc;
}

问题是,编译器不喜欢这段代码

error: use of deleted function 'example1()::<lambda(int)>& example1()::<lambda(int)>::operator=(const example1()::<lambda(int)>&)'

我知道在这种情况下,带有捕获的 lambda 的复制赋值运算符被删除。我不明白的是为什么不调用移动赋值运算符?如果我们要“手动​​”编写 lambda,一切正常:

struct Lambda_sustitution {
    int* acc;
    Lambda_sustitution() = default;
    Lambda_sustitution(int& acc) : acc{&acc} {}

    Lambda_sustitution(const Lambda_sustitution&) = delete;
    Lambda_sustitution& operator=(const Lambda_sustitution&) = delete;

    Lambda_sustitution(Lambda_sustitution&& s) {
        acc = s.acc;
        s.acc = nullptr;
    }
    
    Lambda_sustitution& operator=(Lambda_sustitution&& s) {
        acc = s.acc;
        s.acc = nullptr;
        return *this;
    }
    void operator()(int i) {*acc += i; };
};

int example2() {
    int acc = 0;
    std::vector<std::vector<int>> values{{1,4}};
    Lambda_sustitution l{acc};
    l = flat_nested_for_each_of_sorts(begin(values),std::move(l));
    return *l.acc;
}

编译器资源管理器链接https://godbolt.org/z/6Tb5WYqxj

解决方法

我不明白的是为什么不调用移动赋值运算符?

因为 lambda 也没有移动赋值运算符(而且它有一个复制构造函数)。


事实上,你不需要做任何重新分配,你可以简单地做:

template <class InputIt,class UnaryFunction>
UnaryFunction flat_nested_for_each_of_sorts(InputIt first,InputIt last,UnaryFunction f) {
    while (first != last) {
        std::for_each(begin(*first),end(*first),f);
        ++first;
    }
    return f;
}

并称之为:

int example1() {
    int acc = 0;
    std::vector<std::vector<int>> values{{1,2},{3,4}};
    auto l = [&acc](int i) {acc += i;};
    flat_nested_for_each_of_sorts(begin(values),end(values),l);
    return acc;
}

Demo

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。