【问题标题】:When reassigning lambda, why called deleted copy assignment instead of move assignment?重新分配 lambda 时,为什么叫删除复制分配而不是移动分配?
【发布时间】:2021-09-25 05:55:39
【问题描述】:

我正在实现某种嵌套平面 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,2},{3,4}};
    Lambda_sustitution l{acc};
    l = flat_nested_for_each_of_sorts(begin(values), end(values), std::move(l));
    return *l.acc;
}

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

【问题讨论】:

    标签: c++11 lambda


    【解决方案1】:

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

    因为 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 2021-02-14
      • 2016-07-20
      • 2013-09-10
      • 2012-07-21
      • 2018-02-16
      • 1970-01-01
      相关资源
      最近更新 更多