这个问题花了我几个小时,但我不明白我做错了什么。
这是编译错误消息:
错误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安装。
答案 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));
我对此并不确定,但请告诉我结果如何。