C++

2009-12-11 20 views
6

'daki üye işlevlerine ilişkin işlev işaretçileri Bir işlev işaretçisini bekleyen bir yöntemi çağırmam gerekiyor, ancak gerçekten ona geçmek istediğim bir eğlenceli işlev. İşte yapmak ne çalışıyorum, bir örnek: Ben son satırı almak için bir yol bulmak mümkün olmamıştırC++

#include <iostream> 
#include "boost/function.hpp" 

typedef int (*myAdder)(int); 

int adderFunction(int y) { return(2 + y); } 

class adderClass { 
    public: 
    adderClass(int x) : _x(x) {} 
    int operator() (int y) { return(_x + y); } 

    private: 
    int _x; 
}; 

void printer(myAdder h, int y) { 
    std::cout << h(y) << std::endl; 
} 

int main() { 
    myAdder f = adderFunction; 

    adderClass *ac = new adderClass(2); 
    boost::function1<int, int> g = 
    std::bind1st(std::mem_fun(&adderClass::operator()), ac); 

    std::cout << f(1) << std::endl; 
    std::cout << g(2) << std::endl; 
    printer(f, 3); 
    printer(g, 4); // Is there a way to get this to work? 
} 

, yazıcı (g, 4), derlemek. Bunu işe almak için bir yolu var mı? Kontrolümdeki tek şey "ana" ve "adderClass" sınıfı. şöyle

cevap

0

:

template<typename AdderT> 
void printer(AdderT h, int y) { 
    std::cout << h(y) << std::endl; 
} 

Ayrıca, boost::function gerekmez. Bunu yapabilirsin:

adderClass ac(2); 
    std::cout << f(1) << std::endl; 
    std::cout << ac(2) << std::endl; 
    printer(f, 3); 
    printer(ac, 4); 
+0

Bu işe yarar, ama (bahsetmeyi unuttum), "yazıcı" yönteminde kod değiştiremiyorum. – JamieC

+0

Tüm bunlar benim kontrolümde "ana" ve "adderClass" sınıfı. – JamieC

0

Yükseltme işlevi normal işlev işaretçisi gibi davranırken farklı bir türdür. Bu nedenle, bir işlev işaretçisine bir yükseltme işlevi atayamazsınız. Kodunuzda

sadece

typedef boost::function1< int, int > myAdder; 

ile

typedef int (*myAdder)(int); 

yerini alabilir ve her şeyi çalışırdı.

2

Ok, burada başka bir denemeydi:

class CallProxy 
{ 
public: 
    static adderClass* m_instance; 
    static int adder(int y) 
    { 
     return (*m_instance)(y); 
    } 
}; 

adderClass* CallProxy::m_instance = NULL; 


int main() { 
    myAdder f = adderFunction; 

    adderClass ac(2); 

    std::cout << f(1) << std::endl; 
    std::cout << ac(2) << std::endl; 
    printer(f, 3); 
    CallProxy::m_instance = &ac; 
    printer(CallProxy::adder, 4); 
} 

Sorun, printer bunu bir işlev işaretçisi göndermelidir böylece bir işlev işaretçisi ve başka bir şey almak için sahip olarak derlenmiş olması. Bir işlev işaretçisi ile örneğinizi tutacak kimse yoktur. Yani bu çözüm, statik bir veri elemanı kullanarak yapar.

Bu kodun iş parçacığı güvenliğini sağladığını unutmayın. Aynı anda main'u çalıştıran iki iş parçacığı, m_instance'a iki farklı şey koyabilir.

+1

Aynı zamanda yeniden giriş yapmıyor: eğer '' '' '' '' '' '' '' '' '' '' '' dır, sorun çıkarırsanız. Ama bence en azından portatif olarak kısıtlamalar göz önüne alındığında yapılabilecek en iyisi. Taşınabilir olmayan çözümler için, örneğin anında kod üretebilirsiniz. –

+0

@Steve Jessop: 'main()' olarak adlandırılan her şey, tanımlanmamış davranışlara neden olur (§3.6.1/2: "Bir program içinde fonksiyon ana (3.2) kullanılmayacaktır.) –

+0

@Jerry Coffin - deneyin Bu aptal örneğin sınırlı sınırlarının ötesine bakın. – shoosh