lambda中的捕获变量会导致混淆

tom*_*udm 1 c++ lambda c++11

我有一个为文明V创建地图的应用程序.作为一个有趣的设计选择,我决定创建一些函数来为我循环遍历地图.这样我就可以将函数指针或lambda函数传递给该函数,该函数遍历整个映射,为每个tile执行某些操作.这背后的推理是,如果我或其他人改变地图的存储方式(从2D数组到2D矢量或其他),人们只需要改变一个函数而不是整个代码库.

现在问题出在这里,首先是一些代码.

错误代码.

    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;
Run Code Online (Sandbox Code Playgroud)

头文件中的定义.

void loop_through(void (*)(Tile* t));
void loop_through_limit(Tile* (*)(Tile* t), int start_x, int start_y, int width, int height);
Run Code Online (Sandbox Code Playgroud)

现在每种情况的差异与注释掉的代码差别不大.这很好用.当我注释掉if语句块时,那么这就是我的输出.

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*)’
Run Code Online (Sandbox Code Playgroud)

我相信当我开始使用我试图通过引用捕获的参数时问题就出现了.然后它开始变成一个"lambda"函数,而不仅仅是一个"函数指针",也许我只是没有得到它.

有什么建议?

Naw*_*waz 5

如果C++ 11 lambda捕获变量,它们不是函数指针.您需要的是什么std::function,特别是对于第二个函数,因为该捕获变量的lambda.

所以改变这些:

void loop_through(void (*)(Tile* t));
void loop_through_limit(Tile* (*)(Tile* t), /*...*/);
Run Code Online (Sandbox Code Playgroud)

这些:

void loop_through(std::function<void(Tile*)>  fun);
void loop_through_limit(std::function<Tile*(Tile*)> fun, /*...*/);
Run Code Online (Sandbox Code Playgroud)

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