Почему переменная становится "const", когда я использую захват [=] (используя класс Lambda)?

Помещение № 1: я уже решил ошибку, но я не очень понял причину ошибки компилятора.

Помещение № 2. Цель этой программы - скопировать изображение в другое изображение с помощью многопоточного процесса. Возможно, лучший способ существует, но это не является основной темой вопроса (см. Предположение № 1).

Я написал простую программу, использующую библиотеку OpenCV 3.1, чтобы скопировать изображение в другое изображение. Он использует все ядра процессора, используя больше потоков.

Код:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <thread>

using namespace cv;
using namespace std;

#define IMG_PATH "..\\img\\50a.png"


void copy_image(const Mat& input, Mat& output, int row_offset, int skip_row)
{
    cout << row_offset;
    Size size = input.size();
    for (int r = row_offset; r < size.height; r += skip_row)
    {
        for (int c = 0; c < size.width; c++)
        {
            output.at<Vec3b>(r, c) = input.at<Vec3b>(r, c);
        }
    }
}

int main()
{
    Mat input_img = imread(IMG_PATH);
    Mat output_img = Mat(input_img.size(), input_img.type()); output_img.setTo(255);

    vector<thread> threads;
    int thread_number = thread::hardware_concurrency();

    for (int i = 0; i < thread_number; i++)
    {
        cout << i;
        auto var = [=]() 
        {
            return copy_image(input_img, output_img, i, thread_number);
        };

        threads.push_back(thread(var));
    }

    for (auto& thread : threads) 
        thread.join();

    imshow("output_img", output_img);
    imwrite("result.png", output_img);
    waitKey(0);
}

Компилятор возвращает мне эту ошибку

Ошибка C2664 'void copy_image (const cv:: Mat &, cv:: Mat &, int, int)': не может преобразовать аргумент 2 из 'const cv:: Mat' в 'cv:: Mat &'

что он возвращает эту строку кода:

return copy_image(input_img, output_img, i, thread_number);

Я решил эту ошибку заменить эту строку

auto var = [=]()

с этим

auto var = [=, &input_img, &output_img]() 

но на самом деле я не очень понимаю, почему я получил эту ошибку.

Ответ 1

Если вы сделаете захват по значению в лямбда, вы получите "член", который будет сохранен. Поскольку значение по умолчанию operator() является функцией const, вы не можете изменять их.

Lambdas можно определить как []() mutable {}, чтобы вы могли изменять локальные переменные.

Захватив значение по ссылке, вы имеете что-то, что ведет себя как указатель const к неконстантическому объекту, поэтому без изменчивого вы можете адаптировать эти объекты. (Если они уже не существуют)

Ответ 2

Захваченные переменные действительно const в области lamba:

[foo]()
{
   // foo, whatever that is, is const
}

В изменяемой лямбда захваченные переменные не являются постоянными:

[foo]()
mutable {

   // Lambda can modify foo, but it a copy of the original
   // captured variable
}