Как сделать typedef для функции void, которая может быть свойством любого класса? - PullRequest
1 голос
/ 31 января 2011

Когда мы делаем

typedef void FuncCharPtr(char*, int) ;
vector<FuncCharPtr*> FuncVec ;
void Add(FuncCharPtr* f)
{
    FuncVec.push_back(f);
}

, мы не разрешаем передавать как типы FuncCharPtr, такие как

 void (someClass::*)b(char*, int);
 void (someOtherClass::*)b(char*, int);

, и мы хотим сохранить ссылки на функции обоих классов в одном векторе,быть в состоянии звонить всем абонентам одновременно с чем-то вроде

void CastData(char * data, int length){
    for(size_t i = 0 ; i < FuncVec.size(); i++){
        char* dataCopy = new char[length];
        memcpy(dataCopy, data, length);
        FuncVec[i](dataCopy, length);
                    delete[] dataCopy;
    }
}

Как решить такую ​​проблему?

1 Ответ

6 голосов
/ 31 января 2011

Вы не можете использовать указатель на функцию для этого. Тип класса является частью типа указателя на функцию-член, поэтому нет единого типа, который бы работал.

Лучший способ выполнить то, что вы хотите сделать, это использовать класс function и функцию bind от Boost, C ++ TR1 или C ++ 0x ,

Вы можете поддерживать std::vector<std::function<void(char*, int)> > и использовать функцию bind для привязки указателей на функции-члены к экземпляру класса, для которого вы хотите, чтобы функция-член вызывалась:

struct A { void foo(int) { } };
struct B { void bar(int) { } };

typedef std::function<void(int)>   Function;
typedef std::vector<Function>      FunctionSequence;
typedef FunctionSequence::iterator FunctionIterator;

FunctionSequence funcs;

A a;
B b;

funcs.push_back(std::bind(&A::foo, &a, std::placeholders::_1));
funcs.push_back(std::bind(&B::bar, &b, std::placeholders::_1));

// this calls a.foo(42) then b.bar(42):
for (FunctionIterator it(funcs.begin()); it != funcs.end(); ++it)
    (*it)(42);
...