2016-02-10 24 views
6

Aşağıdaki kodu derlerken:şablon sınıfından genel std :: işlev üyesini arayamaz

#include <functional> 

template <typename functionSignature> 
class Class 
{   
    std::function<functionSignature> func; 
public: 
    Class(const std::function<functionSignature>& arg) : func(arg) {} 
    void callFunc() { func(); } 
}; 

void f(const int i) {} 

int main() 
{ 
    Class<void(const int)> a(std::bind(f, 10)); 
    a.callFunc(); 
    return 0; 
} 

VS 2015 derleyici altıncı satırında aşağıdaki hata iletisini oluşturur: Şimdi

error C2064: term does not evaluate to a function taking 0 arguments. 

, Bunun, derleyicinin functionSignature'un bir işlev imzası olmadığını düşündüğüne inanıyorum; Örnekleme yaptığımda aynı hata oluşur ve örneğin, , std::function<int()> yerine birnumaralı telefondan aramayı deneyin.

Şablon bağımsız değişkeninin her zaman bir işlev imzası olacağından nasıl emin olabilirim, böylece 'u std::function numaralı telefondan arayabilir miyim?

template <typename F> 
class Class; 

template<typename R, typename... P> 
class Class<R(P...)> { 
public: 
    std::function<R(P...)> func; 
    void callFunc(P... p) { func(p...); } 
}; 

kısmi uzmanlaşma kolayca istediğiniz türü tanımlayabilirsiniz bu şekilde kullanarak:

+0

için serseri hattını değiştirmek? – Jts

+0

Evet, gerçek bir MCVE yardımcı olur. Sadece bir '' '' '' '' 'class'ın bir örneğini 'Class Yakk

cevap

2

Sizin hata buradadır:

Class<void(const int)> a(std::bind(f, 10)); 

fonksiyon Class::callFunc()func() çağırır - yani hiçbir argüman. std::bind(f, 10) sonucu, aynı zamanda, sınıf şablonuna ilişkin şablon bağımsız değişkeniyle tutarlı olan hiçbir argüman almayan bir işlevdir. Class<void(const int)>'u kullanmak, hem sınıf şablonundaki kullanımı hem de başlatma işlemiyle tutarsızdır.

çözüm kolaydır: Eğer sınıf arayarak ve nasıl sınıfını başlatmak tam olarak nasıl kodunuzu güncelleyin Can

Class<void()> a(std::bind(f, 10)); 
+0

Peki, OP orijinal soruyu değiştirdiği için, ilk cevabım hala mantıklı, ama bu daha çok odaklanmış durumda. – skypjack

+1

@skypjack - Cevabınızı yazdığınız sırada devam edecek fazla bir şey yoktu. OP'nin aklını okudun, sonra da biraz. Cevabınız + 1, yani. –

6

Ben böyle bir şey istiyorum şüpheli. Bunu func iyi bir fikir değil çağırmak için, sınıfınız için hiçbir kurucuya sahip olduğunu fark ettim Tabii

Class<int(double)> c; 

, ama bunu tanımlamak oldukça kolay: Bir örnek olarak
, sen olarak kullanabilirsiniz ve argüman olarak uygun bir işlevi iletir.

Ben işlevini çağırmak için operator() kullandım tam ve çalışma örneği aşağıdaki gibidir:

#include <functional> 

template <typename F> 
class Class; 

template<typename R, typename... P> 
class Class<R(P...)> { 
public: 
    Class(std::function<R(P...)> f): func{f} { } 
    void operator()(P... p) { func(p...); } 
private: 
    std::function<R(P...)> func; 
}; 

void fn() { } 

int main() { 
    std::function<void()> f = fn; 
    Class<void()> c{f}; 
    c(); 
} 
+0

+1, Bu benim googled soruyu cevapladı ve bunun soru başlığı ile ilgili olduğunu düşündüm. – AnorZaken

1

bu yapmaya çalıştığın ne mi?

http://ideone.com/fork/IZ0Z1A

functionSignature DEĞİLSE sen Class oluştururken bir işlev, std :: fonksiyon hata verir ancak bir kurucu ekleyin ve sanırım isterseniz orada static_assert(std::is_function<functionSignature>::value == true," "); atabilir.

#include <functional> 
#include <iostream> 

template <typename functionSignature> 
class Class 
{ 
public: 
    std::function<functionSignature> func; 
    void callFunc() { func(); } 
}; 

void f() 
{ 
    std::cout << "hello" << std::endl; 
} 

int main() 
{ 
    Class<decltype(f)> t {f}; 
    t.callFunc(); 

    return 0; 
} 
İlgili konular