如何有条件地定义lambda?

Mon*_*mer 10 c++

以下功能将在加载的图像上随机“撒盐”。为了提高性能,条件语句

uint j = rows == 1 ? 0 : randomRow(generator);
Run Code Online (Sandbox Code Playgroud)

不应在循环内。

相反,我想getJ在循环之前定义一个lambda 作为

auto getJ = rows == 1 ? []() {return 0; } : []() {return randomRow(generator); };
Run Code Online (Sandbox Code Playgroud)

但是,我的带有此lambda的代码无法使用以下红色弯曲文本进行编译:

在此处输入图片说明

如何有条件地定义这样的lambda?

void salt_(Mat mat, unsigned long long n)
{
    const uchar channels = mat.channels();
    uint cols = mat.cols;
    uint rows = mat.rows;

    if (mat.isContinuous())
    {
        cols *= rows;
        rows = 1;
    }

    default_random_engine generator;
    uniform_int_distribution<uint> randomRow(0, rows - 1);
    uniform_int_distribution<uint> randomCol(0, cols - 1);



    // auto getJ = rows == 1 ? []() {return 0; } : []() {return randomRow(generator); };


    uchar * const data = mat.data;

    for (unsigned long long counter = 0; counter < n; counter++)
    {
        uint i = randomCol(generator);
        uint j = rows == 1 ? 0 : randomRow(generator);
        //uint j = getJ();

        uint index = channels * (cols * j + i);
        for (uchar k = 0; k < channels; k++)
            data[index + k] = 255;
    }
}
Run Code Online (Sandbox Code Playgroud)

Vit*_*meo 10

我的带有此lambda的代码无法使用以下红色弯曲的文本进行编译

您不能randomRow在不事先捕获 lambda表达式主体的情况下使用它,因为生成的闭包对象需要访问它。

即使您使用[&randomRow],代码也仍然无法编译,因为每个lambda表达式都会产生一个唯一类型的闭包,即使lambda表达式完全相同。

您可以从头开始解决该问题,以避免任何开销并实现所需的功能-创建一个使用您要调用的lambda 的函数:

template <typename F>
void saltImpl(F&& getJ, /* ... */)
{
    uchar * const data = mat.data;

    for (unsigned long long counter = 0; counter < n; counter++)
    {
        uint i = randomCol(generator);
        uint j = rows == 1 ? 0 : randomRow(generator);
        //uint j = getJ();

        uint index = channels * (cols * j + i);
        for (uchar k = 0; k < channels; k++)
            data[index + k] = 255;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

void salt_(Mat mat, unsigned long long n)
{
    const uchar channels = mat.channels();
    uint cols = mat.cols;
    uint rows = mat.rows;

    if (mat.isContinuous())
    {
        cols *= rows;
        rows = 1;
    }

    default_random_engine generator;
    uniform_int_distribution<uint> randomRow(0, rows - 1);
    uniform_int_distribution<uint> randomCol(0, cols - 1);

    if (rows == 1)
    {
        saltImpl([]{ return 0; }, /* ... */);
    }
    else
    {
        saltImpl([&]{ return randomRow(generator); }, /* ... */)
    }
}
Run Code Online (Sandbox Code Playgroud)