c++ - lambda 函数中的捕获变量混淆

标签 c++ lambda c++11

我有一个为文明 V 创建 map 的应用程序。作为一个有趣的设计选择,我决定创建几个函数来为我循环遍历 map 。这样我就可以将一个函数指针或一个 lambda 函数传递给那个遍历整个 map 的函数,对每个图 block 做一些事情。这背后的原因是,如果我或其他人改变 map 的存储方式(从 2D 数组到 2D vector 或其他),则只需要更改一个函数而不是整个代码库。

现在是问题,这里先是一些代码。

错误代码。

    case ALL_SNOW:
        m.loop_through_limit([] (Tile* t) {
            t = new Snow(t->get_x(), t->get_y()); 
            return t;
        }, x, y, width, height);
        break;
    case PTN_ONE:
        m.loop_through_limit([&] (Tile* t) {
            int cur_x = t->get_x();
            int cur_y = t->get_y();
            t = new Plains(cur_x, cur_y);
            // if (y <= height/4 || y >= (height*3)/4) {
            //     Top quarter rows and bottom quarter rows
            //     t = new Ocean(cur_x, cur_y);
            // } else if (cur_x <= width/4) {
            //     Leftmost columns
            //     t = new Ocean(cur_x, cur_y);
            // } else if (cur_x >= (width*3)/4) {
            //     Rightmost columns
            //     t = new Desert(cur_x, cur_y);
            // } 
            return t;
        }, x, y, width, height);
        break;

来自头文件的定义。

void loop_through(void (*)(Tile* t));
void loop_through_limit(Tile* (*)(Tile* t), int start_x, int start_y, int width, int height);

现在,除了注释掉的代码外,每种情况下的区别都没有太大区别。这很好用。当我注释掉 if 语句 block 时,这就是我的输出。

c++ -c  -g -O3 -ffast-math -Wall -Weffc++ -std=c++0x -o tile_block.o tile_block.cpp 
tile_block.cpp: In static member function ‘static void TileBlock::write(Map&, TileBlock::Patterns, int, int, int, int)’:
tile_block.cpp:82:35: error: no matching function for call to ‘Map::loop_through_limit(TileBlock::write(Map&, TileBlock::Patterns, int, int, int, int)::<lambda(Tile*)>, int&, int&, int&, int&)’
tile_block.cpp:82:35: note: candidate is:
map.h:26:10: note: void Map::loop_through_limit(Tile* (*)(Tile*), int, int, int, int)
map.h:26:10: note:   no known conversion for argument 1 from ‘TileBlock::write(Map&, TileBlock::Patterns, int, int, int, int)::<lambda(Tile*)>’ to ‘Tile* (*)(Tile*)’

我相信当我开始使用我试图通过引用捕获的参数时,问题就来了。然后它开始变成一个“lambda”函数,而不仅仅是一个“函数指针”,也许我只是不明白。

有什么建议吗?

最佳答案

如果 C++11 lambda 捕获变量,则它们不是函数指针。您需要的是 std::function,尤其是对于第二个函数,因为该函数的 lambda 捕获变量。

所以改变这些:

void loop_through(void (*)(Tile* t));
void loop_through_limit(Tile* (*)(Tile* t), /*...*/);

对这些:

void loop_through(std::function<void(Tile*)>  fun);
void loop_through_limit(std::function<Tile*(Tile*)> fun, /*...*/);

现在您可以将 lambda 传递给上述函数。

关于c++ - lambda 函数中的捕获变量混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11712228/

相关文章:

c++ - C++中的逗号运算符

c++ - 可以将 &my_boost_array_variable[2] 传递给期望 void* 的 C 函数吗?

c++ - 如何在 lambda 捕获列表中创建指针?

c++ - 使用 decltype() 和 SFINAE 的错误

c++ - 尽管数据匹配预期值,但 compare_exchange_strong 失败

multithreading - C++ std::mutex和Windows CreateMutex有什么区别

c++ - 我无法为二维数组赋值

c++ - QToolButton 在 Windows 中不可见

c++ - []<typename>(){} 是有效的 lambda 定义吗?

c# - 如何在以后设置属性值