1

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

这是编译错误消息:

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

错误位于函数中的 mem_fn.hpp 中dm::operator()我在此处粘贴了文件(第 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,在这里通过“简单方法”安装。

4

1 回答 1

4

我认为您的问题源于此:

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

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

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

不过,我不确定这一点,所以让我知道结果如何。

于 2014-05-16T06:08:08.090 回答