将boost :: bind成员函数传递给wt侦听器..我做错了什么?

时间:2014-05-16 04:12:29

标签: c++ boost wt

这个问题花了我几个小时,但我不明白我做错了什么。

这是编译错误消息:

  

错误113错误C2298:'return':指向成员函数表达式的指针的非法操作c:\ program files \ wt 3.3.2 msvs2012 x86 \ include \ boost \ bind \ mem_fn.hpp 342 1垄断

错误位于函数dm::operator()中的mem_fn.hpp中。我粘贴文件here(第342行)。

我猜这个问题源自boost::bind(),但我检查了我绑定的函数,并且所有似乎都有正确数量的参数。

#include <Wt/WApplication>
#include <Wt/WPushButton>
#include <Wt/WTable>
#include <Wt/WEnvironment>
#include <Wt/WServer>
#include <vector>

using namespace Wt;
using std::vector;
using std::string;

enum Tile {
    N, X, O
};



class TicTacToeGame;

class TicTacToeClient: public WApplication {
public:
    TicTacToeClient(const WEnvironment& env);

    void connectFrom(TicTacToeGame& game);

    void setTile(Tile t);

    void updateBoard(int, int, Tile);

private:
    void takeMove(int i, int j);
    Tile tile;
    Signal<int, int, Tile>* moveTaken;
    WTable* table;

};




class TicTacToeGame {
public:
    static vector<TicTacToeGame*> games;

    TicTacToeGame(TicTacToeClient* x): playerX(x) {
        for(int i=0;i<3;i++){
            vector<Tile> line;
            for(int j=0;j<3;j++)
                line.push_back(Tile::N);
            grid.push_back(line);
        }
        playerX->connectFrom(*this);
        playerX->setTile(Tile::X);
        playerX->enableUpdates();
    }

    void updateBoard(int x, int y, Tile t){
        playerX->environment().server()->post(playerX->sessionId(), boost::bind(&TicTacToeClient::updateBoard, playerX, x, y, t));
        playerO->environment().server()->post(playerO->sessionId(), boost::bind(&TicTacToeClient::updateBoard, playerO, x, y, t));
    }

    void join(TicTacToeClient* o){
        playerO = o;
        playerO->connectFrom(*this);
        playerO->setTile(Tile::O);
        playerO->enableUpdates();
    }

private:
    vector<vector<Tile>> grid;
    TicTacToeClient* playerX;
    TicTacToeClient* playerO;
};

vector<TicTacToeGame*> TicTacToeGame::games = vector<TicTacToeGame*>();

TicTacToeClient::TicTacToeClient(const WEnvironment& env): WApplication(env), moveTaken(new Signal<int, int, Tile>){
    WTable* table = new WTable();
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            WPushButton* button = new WPushButton();
            button->setWidth(50);
            button->setHeight(50);
            button->clicked().connect(boost::bind(&TicTacToeClient::takeMove, this, i, j));
            WTableCell* cell = table->elementAt(i,j);
            cell->addWidget(button);
            cell->setHeight(50);
            cell->setWidth(50);
        }
    }
    root()->addWidget(table);
    this->table = table;
}

void TicTacToeClient::connectFrom(TicTacToeGame& game){
    moveTaken->connect(boost::bind(&TicTacToeGame::updateBoard, &game));
}

void TicTacToeClient::setTile(Tile t){tile = t;}

void TicTacToeClient::updateBoard(int x, int y, Tile t){
    WTableCell* cell = table->elementAt(x, y);
    cell->clear();
    string text;
    switch(t){
    case Tile::X:
        text = "X";
        break;
    case Tile::O:
        text = "O";
        break;
    }
    cell->addWidget(new WText(text));
}


void TicTacToeClient::takeMove(int i, int j){
    moveTaken->emit(i, j, tile);
}

WApplication *createApplication(const WEnvironment& env)
{
    TicTacToeClient* client = new TicTacToeClient(env);
    if(TicTacToeGame::games.empty())
        TicTacToeGame::games.push_back(new TicTacToeGame(client));
    else
        TicTacToeGame::games[0]->join(client);
    return client;
}

int main(int argc, char **argv)
{
    return WRun(argc, argv, &createApplication);
}

我使用的是32位Win7,MSVS Express 2012,Wt是3.3.2,由“简单方法”here安装。

1 个答案:

答案 0 :(得分:4)

我认为你的问题源于此:

void TicTacToeClient::connectFrom(TicTacToeGame& game){
    moveTaken->connect(boost::bind(&TicTacToeGame::updateBoard, &game));
}

绑定调用对象(&amp; game),但该函数需要3个参数。我不熟悉Wt,但看起来moveTaken信号将使用正确的参数调用该函数。在这种情况下,您只需要在boost :: bind调用中添加占位符。

moveTaken->connect(boost::bind(&TicTacToeGame::updateBoard, &game, _1, _2, _3));

我对此并不确定,但请告诉我结果如何。