2013-09-25 31 views
6

Genel işlev işaretçisi şablon parametresi olarak kullanılabilir mi? İşlev işaretçisi şablonu, serbest işlevleri, üye işlevlerini ve lambda işlevlerini kabul edebilir. Normal bir şablon argümanı bir işlev başvurabilirsinizGenel işlev işaretçisi şablon parametresi olarak nasıl kullanılır?

template<class ArgumentT, class ReturnT, typename F*> 
struct A { 
    //use F* to refer to f somewhere 
}; 
+0

Bunu yapabilirsiniz, ancak farklı işlev türü örneklemeleri için farklı uyumsuz türler elde edersiniz. Yani, ArgumentT ve ReturnT aynı olsa bile, üye işlevine bir işaretçi ile A için genel işlev göstergesine sahip bir A atayamazsınız. – ComicSansMS

cevap

8

: Kolaylık olması açısından, görevlerini üstlenmesi Sen tiplerini ve verileri birleştirerek ediyoruz

template<class ArgumentT, class ReturnT, function* f> 
struct A 
{ 
    // f is used somewhere. 
}; 
0

gibi tek parametreye sahiptir, daha böyle bir şey istiyorum. Eğer aynı kolaylıkla operator() overloads bazı sınıfını kullanın ve (aslında, bu sıklıkla tercih edilen yöntemdir ve) bunun yerine uygulayarak herhangi - gerçi bir işleve şablon argümanı kısıtlayan bir şey yok

#include <iostream> 

template <class ArgT, class RetT, class F> 
struct A { 
    F f; 
public: 
    A(F f) : f(f) {} 

    RetT operator()(ArgT arg) { return f(arg); } 
}; 

int unchanged(int i) { return i; } 

int main(){ 
    A < int, int, int(*)(int)> t{ unchanged }; 

    for (int i = 0; i < 10; i++) 
     std::cout << t(i) << "\n"; 
} 

.

+2

Bu dilbilgisi doğru mu? – user1899020

0

Sen ile yakın bir şey elde edebilirsiniz:

template<class ArgumentT, class ReturnT, class F, F f> 
struct A; 

template<class ArgumentT, class ReturnT, ReturnT (*f)()> 
struct A<ArgumentT, ReturnT, ReturnT (*)(), f> 
{ 
    // f is used somewhere. 
}; 

template<class ArgumentT, class ReturnT, class C, ReturnT (C::*f)()> 
struct A<ArgumentT, ReturnT, ReturnT (C::*)(), f> 
{ 
    // f is used somewhere. 
}; 

... ama olmayan bir tip şablon parametresi olarak bir std::function<ReturnT()> gibi bir şey alamaz. Fonksiyon göstergelerinin uzmanlaşması, yakalamayan lambdaları da kabul edecektir. C++ 11 kullanın veya artırmak :: fonksiyonunu <> eğer

2

Ben std :: işlevini <> kullanmak öneriyoruz bunu yapamıyorsanız: Eğer işlev işaretçisi geçebilir Bu durumda

template<class ArgumentT, class ReturnT > struct A { 
    typedef std::function< ReturnT(ArgumentT) > Function; 
    void foobar(Function f) { ReturnT ret = f(arg); } 
}; 

, functor, lambda ya da std :: bind ya da boost'u kullanın :: imzanın uyuşmadığı hemen hemen her işleve bağlanın. Bu durumda şablona ihtiyacınız olduğundan emin değilim, std :: işlevini doğrudan kullanabilirsiniz, ancak bu kodunuza bağlıdır.

+2

Std :: işlevini kullanmanın pek çok olumsuz yanı vardır, bu nedenle battaniye tavsiyesi değildir. – xaxxon

İlgili konular