Передача функции-члена boost::bind слушателю wt... что я сделал не так?

Эта проблема заняла у меня несколько часов, и все же я немного не понимаю, что я сделал не так.

Это сообщение об ошибке компиляции:

Ошибка 113 ошибка C2298: «возврат»: недопустимая операция над указателем на выражение функции-члена 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, устанавливал "простым методом" здесь.


person T Tse    schedule 16.05.2014    source источник


Ответы (1)


Я думаю, что ваша проблема связана с этим:

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));

Я не уверен в этом, поэтому дайте мне знать, как это получается.

person jhoffman0x    schedule 16.05.2014