2016-04-14 48 views
2

Geçenlerde buna benzer bir sınıf ilan var: Ben geçirilen bağlı üye işlevine işaretçisi almak istiyorum Bu örnektekullanın std :: fonksiyon sarmak için statik olmayan üye işlev işaretçisi

class Foo { 
public: 
    void run(); 
private: 
    void foo(); 
    void boo(); 
    void doo(); 
    std::function<void()>getFunction(int); 
}; 

tamsayı.

void Foo::run(){ 
    std::function<void()> f; 
    for(int i = 0; i < 3; i++){ 
     f = getFunction(i); 
     f(); 
    } 
} 

std::function<void()>Foo::getFunction(int i){ 
    switch(i){ 
     case 0: return foo; 
     case 1: return Foo::boo; 
     case 2: return this->*doo; 
    } 
} 

Tüm durumlar derleyici hatalarına neden olur. case 1 için çalışmak üzere static ekleniyor ancak statik üyeler kullanmamayı tercih ediyorum.

static anahtar sözcüğünü kullanmadan bu işaretçileri düzgün şekilde almanın bir yolu var mı?

+0

Statik işlevini kullanmamayı tercih (bunu varsayarak önemlidir kendileri tarafından iç fonksiyonları değil işlev işaretçileri çağırmak için güçlü olmak meselesi), ancak bu durumda sizi fonksiyonunuzu benzersiz parametrelerle benzersiz bir şekilde kullanın, semantik olarak buna değer mi? Ve hala bir yorum olarak, bir işleve erişmek için bu tür bir yöntemin kullanılması ve/veya uzatılması kolay olacaktır. Belki bir Enum kullanmak daha açık olacaktır. –

cevap

3

en lambdas kullanma hakkında

Ne cevap songyuanyao için?

void Foo::run(){ 
    std::function<void()> f; 
    for(int i = 0; i < 3; i++){ 
     f = getFunction(i); 
     f(); 
    } 
} 

std::function<void()> Foo::getFunction(int i) { 
    switch(i){ 
     case 0: return [this](){this->foo();}; 
     case 1: return [this](){this->boo();}; 
     case 2: return [this](){this->doo();}; 
    } 
} 

LIVE3

+0

Bu çözüm bana güzel görünüyor ve çalışıyor. Çok teşekkürler! – Giebut

2

Statik olmayan üye işlevini çağırmak için bir nesneyi bağlamanız gerekir, bu durumda bu, this. Sen, std::bind kullanabilirsiniz

LIVE1

Ya statik olmayan üye işlev için maç için, std::function<void(Foo&)> için std::function<void()> değiştirmek

std::function<void()> Foo::getFunction(int i) { 
    switch(i){ 
     case 0: return std::bind(&Foo::foo, *this); // or std::bind(&Foo::foo, this) 
     case 1: return std::bind(&Foo::boo, *this); // or std::bind(&Foo::boo, this) 
     case 2: return std::bind(&Foo::doo, *this); // or std::bind(&Foo::doo, this) 
    } 
} 

. Sonra bir uzantısı olarak

void Foo::run() { 
    std::function<void(Foo&)> f; 
    for(int i = 0; i < 3; i++) { 
     f = getFunction(i); 
     f(*this); 
    } 
} 

std::function<void(Foo&)> Foo::getFunction(int i) { 
    switch(i){ 
     case 0: return &Foo::foo; 
     case 1: return &Foo::boo; 
     case 2: return &Foo::doo; 
    } 
} 

LIVE2